diff --git a/.buildkite/scripts/common/env.sh b/.buildkite/scripts/common/env.sh index ac80a66d33fa0..cd33cdc714cbe 100755 --- a/.buildkite/scripts/common/env.sh +++ b/.buildkite/scripts/common/env.sh @@ -36,7 +36,12 @@ export ELASTIC_APM_ENVIRONMENT=ci export ELASTIC_APM_TRANSACTION_SAMPLE_RATE=0.1 if is_pr; then - export ELASTIC_APM_ACTIVE=false + if [[ "${GITHUB_PR_LABELS:-}" == *"ci:collect-apm"* ]]; then + export ELASTIC_APM_ACTIVE=true + else + export ELASTIC_APM_ACTIVE=false + fi + export CHECKS_REPORTER_ACTIVE=true # These can be removed once we're not supporting Jenkins and Buildkite at the same time diff --git a/.buildkite/scripts/common/persist_bazel_cache.sh b/.buildkite/scripts/common/persist_bazel_cache.sh new file mode 100755 index 0000000000000..357805c11acec --- /dev/null +++ b/.buildkite/scripts/common/persist_bazel_cache.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +source .buildkite/scripts/common/util.sh + +KIBANA_BUILDBUDDY_CI_API_KEY=$(retry 5 5 vault read -field=value secret/kibana-issues/dev/kibana-buildbuddy-ci-api-key) +export KIBANA_BUILDBUDDY_CI_API_KEY + +# overwrites the file checkout .bazelrc file with the one intended for CI env +cp "$KIBANA_DIR/src/dev/ci_setup/.bazelrc-ci" "$KIBANA_DIR/.bazelrc" + +### +### append auth token to buildbuddy into "$KIBANA_DIR/.bazelrc"; +### +echo "# Appended by .buildkite/scripts/persist_bazel_cache.sh" >> "$KIBANA_DIR/.bazelrc" +echo "build --remote_header=x-buildbuddy-api-key=$KIBANA_BUILDBUDDY_CI_API_KEY" >> "$KIBANA_DIR/.bazelrc" diff --git a/.buildkite/scripts/common/setup_bazel.sh b/.buildkite/scripts/common/setup_bazel.sh deleted file mode 100755 index bbd1c58497172..0000000000000 --- a/.buildkite/scripts/common/setup_bazel.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -source .buildkite/scripts/common/util.sh - -KIBANA_BUILDBUDDY_CI_API_KEY=$(retry 5 5 vault read -field=value secret/kibana-issues/dev/kibana-buildbuddy-ci-api-key) -export KIBANA_BUILDBUDDY_CI_API_KEY - -cp "$KIBANA_DIR/src/dev/ci_setup/.bazelrc-ci" "$HOME/.bazelrc" - -### -### append auth token to buildbuddy into "$HOME/.bazelrc"; -### -echo "# Appended by .buildkite/scripts/setup_bazel.sh" >> "$HOME/.bazelrc" -echo "build --remote_header=x-buildbuddy-api-key=$KIBANA_BUILDBUDDY_CI_API_KEY" >> "$HOME/.bazelrc" - -### -### remove write permissions on buildbuddy remote cache for prs -### -if [[ "${BUILDKITE_PULL_REQUEST:-}" && "$BUILDKITE_PULL_REQUEST" != "false" ]] ; then - { - echo "# Uploads logs & artifacts without writing to cache" - echo "build --noremote_upload_local_results" - } >> "$HOME/.bazelrc" -fi diff --git a/.buildkite/scripts/lifecycle/pre_command.sh b/.buildkite/scripts/lifecycle/pre_command.sh index be31bb74ef668..cae6a07708d46 100755 --- a/.buildkite/scripts/lifecycle/pre_command.sh +++ b/.buildkite/scripts/lifecycle/pre_command.sh @@ -4,16 +4,17 @@ set -euo pipefail source .buildkite/scripts/common/util.sh -node .buildkite/scripts/lifecycle/print_agent_links.js || true - -echo '--- Job Environment Setup' +BUILDKITE_TOKEN="$(retry 5 5 vault read -field=buildkite_token_all_jobs secret/kibana-issues/dev/buildkite-ci)" +export BUILDKITE_TOKEN +echo '--- Install buildkite dependencies' cd '.buildkite' retry 5 15 yarn install cd - -BUILDKITE_TOKEN="$(retry 5 5 vault read -field=buildkite_token_all_jobs secret/kibana-issues/dev/buildkite-ci)" -export BUILDKITE_TOKEN +node .buildkite/scripts/lifecycle/print_agent_links.js || true + +echo '--- Job Environment Setup' # Set up a custom ES Snapshot Manifest if one has been specified for this build { diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.js b/.buildkite/scripts/pipelines/pull_request/pipeline.js index 068de9917c213..78dc6e1b29b6d 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.js +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.js @@ -60,7 +60,7 @@ const uploadPipeline = (pipelineContent) => { /^x-pack\/test\/security_solution_cypress/, /^x-pack\/plugins\/triggers_actions_ui\/public\/application\/sections\/action_connector_form/, /^x-pack\/plugins\/triggers_actions_ui\/public\/application\/context\/actions_connectors_context\.tsx/, - ]) + ]) || process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') ) { pipeline.push(getPipeline('.buildkite/pipelines/pull_request/security_solution.yml')); } @@ -69,7 +69,7 @@ const uploadPipeline = (pipelineContent) => { // if ( // await doAnyChangesMatch([ // /^x-pack\/plugins\/apm/, - // ]) + // ]) || process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') // ) { // pipeline.push(getPipeline('.buildkite/pipelines/pull_request/apm_cypress.yml')); // } diff --git a/.buildkite/scripts/steps/on_merge_build_and_metrics.sh b/.buildkite/scripts/steps/on_merge_build_and_metrics.sh index b24e585e70735..315ba08f8719b 100755 --- a/.buildkite/scripts/steps/on_merge_build_and_metrics.sh +++ b/.buildkite/scripts/steps/on_merge_build_and_metrics.sh @@ -3,7 +3,7 @@ set -euo pipefail # Write Bazel cache for Linux -.buildkite/scripts/common/setup_bazel.sh +.buildkite/scripts/common/persist_bazel_cache.sh .buildkite/scripts/bootstrap.sh .buildkite/scripts/build_kibana.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 17150e3c98cec..1e0a8b187c778 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -63,7 +63,7 @@ /packages/kbn-interpreter/ @elastic/kibana-app-services /src/plugins/bfetch/ @elastic/kibana-app-services /src/plugins/data/ @elastic/kibana-app-services -/src/plugins/data-views/ @elastic/kibana-app-services +/src/plugins/data_views/ @elastic/kibana-app-services /src/plugins/embeddable/ @elastic/kibana-app-services /src/plugins/expressions/ @elastic/kibana-app-services /src/plugins/field_formats/ @elastic/kibana-app-services @@ -254,7 +254,6 @@ /src/plugins/kibana_overview/ @elastic/kibana-core /x-pack/plugins/global_search_bar/ @elastic/kibana-core #CC# /src/core/server/csp/ @elastic/kibana-core -#CC# /src/plugins/xpack_legacy/ @elastic/kibana-core #CC# /src/plugins/saved_objects/ @elastic/kibana-core #CC# /x-pack/plugins/cloud/ @elastic/kibana-core #CC# /x-pack/plugins/features/ @elastic/kibana-core diff --git a/api_docs/actions.json b/api_docs/actions.json index 5094a7cadefe3..532128e65d926 100644 --- a/api_docs/actions.json +++ b/api_docs/actions.json @@ -695,7 +695,7 @@ "label": "ActionParamsType", "description": [], "signature": [ - "{ readonly source?: string | undefined; readonly summary?: string | undefined; readonly timestamp?: string | undefined; readonly eventAction?: \"resolve\" | \"trigger\" | \"acknowledge\" | undefined; readonly dedupKey?: string | undefined; readonly severity?: \"warning\" | \"error\" | \"info\" | \"critical\" | undefined; readonly component?: string | undefined; readonly group?: string | undefined; readonly class?: string | undefined; }" + "{ readonly source?: string | undefined; readonly summary?: string | undefined; readonly timestamp?: string | undefined; readonly eventAction?: \"resolve\" | \"trigger\" | \"acknowledge\" | undefined; readonly dedupKey?: string | undefined; readonly severity?: \"error\" | \"info\" | \"warning\" | \"critical\" | undefined; readonly component?: string | undefined; readonly group?: string | undefined; readonly class?: string | undefined; }" ], "path": "x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts", "deprecated": false, @@ -751,7 +751,7 @@ "label": "ActionParamsType", "description": [], "signature": [ - "Readonly<{} & { subAction: \"getFields\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"getIncident\"; subActionParams: Readonly<{} & { externalId: string; }>; }> | Readonly<{} & { subAction: \"handshake\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"pushToService\"; subActionParams: Readonly<{} & { incident: Readonly<{} & { description: string | null; category: string | null; severity: string | null; externalId: string | null; urgency: string | null; impact: string | null; short_description: string; subcategory: string | null; }>; comments: Readonly<{} & { comment: string; commentId: string; }>[] | null; }>; }> | Readonly<{} & { subAction: \"getChoices\"; subActionParams: Readonly<{} & { fields: string[]; }>; }> | Readonly<{} & { subAction: \"getFields\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"getIncident\"; subActionParams: Readonly<{} & { externalId: string; }>; }> | Readonly<{} & { subAction: \"handshake\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"pushToService\"; subActionParams: Readonly<{} & { incident: Readonly<{} & { description: string | null; category: string | null; externalId: string | null; short_description: string; subcategory: string | null; dest_ip: string | null; malware_hash: string | null; malware_url: string | null; source_ip: string | null; priority: string | null; }>; comments: Readonly<{} & { comment: string; commentId: string; }>[] | null; }>; }> | Readonly<{} & { subAction: \"getChoices\"; subActionParams: Readonly<{} & { fields: string[]; }>; }>" + "Readonly<{} & { subAction: \"getFields\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"getIncident\"; subActionParams: Readonly<{} & { externalId: string; }>; }> | Readonly<{} & { subAction: \"handshake\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"pushToService\"; subActionParams: Readonly<{} & { incident: Readonly<{} & { description: string | null; category: string | null; severity: string | null; externalId: string | null; urgency: string | null; impact: string | null; short_description: string; subcategory: string | null; correlation_id: string | null; correlation_display: string | null; }>; comments: Readonly<{} & { comment: string; commentId: string; }>[] | null; }>; }> | Readonly<{} & { subAction: \"getChoices\"; subActionParams: Readonly<{} & { fields: string[]; }>; }> | Readonly<{} & { subAction: \"getFields\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"getIncident\"; subActionParams: Readonly<{} & { externalId: string; }>; }> | Readonly<{} & { subAction: \"handshake\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"pushToService\"; subActionParams: Readonly<{} & { incident: Readonly<{} & { description: string | null; category: string | null; externalId: string | null; short_description: string; subcategory: string | null; correlation_id: string | null; correlation_display: string | null; dest_ip: string | string[] | null; malware_hash: string | string[] | null; malware_url: string | string[] | null; source_ip: string | string[] | null; priority: string | null; }>; comments: Readonly<{} & { comment: string; commentId: string; }>[] | null; }>; }> | Readonly<{} & { subAction: \"getChoices\"; subActionParams: Readonly<{} & { fields: string[]; }>; }>" ], "path": "x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts", "deprecated": false, @@ -821,7 +821,9 @@ "label": "ActionsClient", "description": [], "signature": [ - "{ get: ({ id }: { id: string; }) => Promise<", + "{ create: ({ action: { actionTypeId, name, config, secrets }, }: ", + "CreateOptions", + ") => Promise<", { "pluginId": "actions", "scope": "server", @@ -829,9 +831,7 @@ "section": "def-server.ActionResult", "text": "ActionResult" }, - "<Record<string, unknown>>>; delete: ({ id }: { id: string; }) => Promise<{}>; create: ({ action: { actionTypeId, name, config, secrets }, }: ", - "CreateOptions", - ") => Promise<", + "<Record<string, unknown>>>; delete: ({ id }: { id: string; }) => Promise<{}>; get: ({ id }: { id: string; }) => Promise<", { "pluginId": "actions", "scope": "server", @@ -1031,7 +1031,7 @@ "signature": [ "\".servicenow\"" ], - "path": "x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts", + "path": "x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts", "deprecated": false, "initialIsOpen": false }, @@ -1045,7 +1045,7 @@ "signature": [ "\".servicenow-sir\"" ], - "path": "x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts", + "path": "x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts", "deprecated": false, "initialIsOpen": false } @@ -1292,7 +1292,7 @@ "section": "def-server.ActionsClient", "text": "ActionsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"update\" | \"execute\" | \"getAll\" | \"getBulk\" | \"enqueueExecution\" | \"ephemeralEnqueuedExecution\" | \"listTypes\" | \"isActionTypeEnabled\" | \"isPreconfigured\">>" + ", \"create\" | \"delete\" | \"get\" | \"update\" | \"execute\" | \"getAll\" | \"getBulk\" | \"enqueueExecution\" | \"ephemeralEnqueuedExecution\" | \"listTypes\" | \"isActionTypeEnabled\" | \"isPreconfigured\">>" ], "path": "x-pack/plugins/actions/server/plugin.ts", "deprecated": false, diff --git a/api_docs/alerting.json b/api_docs/alerting.json index caf8894c3c8a5..ed62c8ffcfe10 100644 --- a/api_docs/alerting.json +++ b/api_docs/alerting.json @@ -24,7 +24,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<never>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">) => string | ", + "<never>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">) => string | ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -47,7 +47,7 @@ "label": "alert", "description": [], "signature": [ - "{ enabled: boolean; id: string; name: string; tags: string[]; params: never; actions: ", + "{ id: string; name: string; tags: string[]; enabled: boolean; params: never; actions: ", { "pluginId": "alerting", "scope": "common", @@ -1038,7 +1038,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<never>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">, \"enabled\" | \"name\" | \"tags\" | \"actions\" | \"throttle\" | \"consumer\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"notifyWhen\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" + "<never>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">, \"name\" | \"tags\" | \"enabled\" | \"actions\" | \"throttle\" | \"consumer\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"notifyWhen\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" ], "path": "x-pack/plugins/alerting/server/types.ts", "deprecated": false @@ -1568,6 +1568,32 @@ "path": "x-pack/plugins/alerting/server/types.ts", "deprecated": false }, + { + "parentPluginId": "alerting", + "id": "def-server.AlertType.defaultScheduleInterval", + "type": "string", + "tags": [], + "label": "defaultScheduleInterval", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/alerting/server/types.ts", + "deprecated": false + }, + { + "parentPluginId": "alerting", + "id": "def-server.AlertType.minimumScheduleInterval", + "type": "string", + "tags": [], + "label": "minimumScheduleInterval", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/alerting/server/types.ts", + "deprecated": false + }, { "parentPluginId": "alerting", "id": "def-server.AlertType.ruleTaskTimeout", @@ -1650,7 +1676,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[]" + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[]" ], "path": "x-pack/plugins/alerting/server/rules_client/rules_client.ts", "deprecated": false @@ -1767,7 +1793,7 @@ "section": "def-server.RulesClient", "text": "RulesClient" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"resolve\" | \"update\" | \"aggregate\" | \"enable\" | \"disable\" | \"muteAll\" | \"getAlertState\" | \"getAlertInstanceSummary\" | \"updateApiKey\" | \"unmuteAll\" | \"muteInstance\" | \"unmuteInstance\" | \"listAlertTypes\" | \"getSpaceId\">" + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"resolve\" | \"update\" | \"aggregate\" | \"enable\" | \"disable\" | \"muteAll\" | \"getAlertState\" | \"getAlertInstanceSummary\" | \"updateApiKey\" | \"unmuteAll\" | \"muteInstance\" | \"unmuteInstance\" | \"listAlertTypes\" | \"getSpaceId\">" ], "path": "x-pack/plugins/alerting/server/plugin.ts", "deprecated": false, @@ -2111,7 +2137,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<Params>, \"enabled\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"apiKey\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">>" + "<Params>, \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"apiKey\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">>" ], "path": "x-pack/plugins/alerting/server/types.ts", "deprecated": false, @@ -2145,17 +2171,7 @@ "label": "RulesClient", "description": [], "signature": [ - "{ get: <Params extends Record<string, unknown> = never>({ id, includeLegacyId, }: { id: string; includeLegacyId?: boolean | undefined; }) => Promise<Pick<", - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.Alert", - "text": "Alert" - }, - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\"> | Pick<", - "AlertWithLegacyId", - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\" | \"legacyId\">>; delete: ({ id }: { id: string; }) => Promise<{}>; create: <Params extends Record<string, unknown> = never>({ data, options, }: ", + "{ create: <Params extends Record<string, unknown> = never>({ data, options, }: ", "CreateOptions", "<Params>) => Promise<Pick<", { @@ -2165,7 +2181,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">>; find: <Params extends Record<string, unknown> = never>({ options: { fields, ...options }, }?: { options?: ", + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">>; delete: ({ id }: { id: string; }) => Promise<{}>; find: <Params extends Record<string, unknown> = never>({ options: { fields, ...options }, }?: { options?: ", "FindOptions", " | undefined; }) => Promise<", { @@ -2175,7 +2191,17 @@ "section": "def-server.FindResult", "text": "FindResult" }, - "<Params>>; resolve: <Params extends Record<string, unknown> = never>({ id, }: { id: string; }) => Promise<", + "<Params>>; get: <Params extends Record<string, unknown> = never>({ id, includeLegacyId, }: { id: string; includeLegacyId?: boolean | undefined; }) => Promise<Pick<", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.Alert", + "text": "Alert" + }, + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\"> | Pick<", + "AlertWithLegacyId", + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\" | \"legacyId\">>; resolve: <Params extends Record<string, unknown> = never>({ id, }: { id: string; }) => Promise<", { "pluginId": "alerting", "scope": "common", @@ -2225,6 +2251,37 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "alerting", + "id": "def-common.formatDuration", + "type": "Function", + "tags": [], + "label": "formatDuration", + "description": [], + "signature": [ + "(duration: string) => string" + ], + "path": "x-pack/plugins/alerting/common/parse_duration.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.formatDuration.$1", + "type": "string", + "tags": [], + "label": "duration", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/alerting/common/parse_duration.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.getBuiltinActionGroups", @@ -3009,6 +3066,19 @@ "path": "x-pack/plugins/alerting/common/alert.ts", "deprecated": false }, + { + "parentPluginId": "alerting", + "id": "def-common.AlertExecutionStatus.lastDuration", + "type": "number", + "tags": [], + "label": "lastDuration", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/alerting/common/alert.ts", + "deprecated": false + }, { "parentPluginId": "alerting", "id": "def-common.AlertExecutionStatus.error", @@ -3585,6 +3655,45 @@ "description": [], "path": "x-pack/plugins/alerting/common/alert_type.ts", "deprecated": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.AlertType.ruleTaskTimeout", + "type": "string", + "tags": [], + "label": "ruleTaskTimeout", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/alerting/common/alert_type.ts", + "deprecated": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.AlertType.defaultScheduleInterval", + "type": "string", + "tags": [], + "label": "defaultScheduleInterval", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/alerting/common/alert_type.ts", + "deprecated": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.AlertType.minimumScheduleInterval", + "type": "string", + "tags": [], + "label": "minimumScheduleInterval", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/alerting/common/alert_type.ts", + "deprecated": false } ], "initialIsOpen": false @@ -4044,7 +4153,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\"> & Pick<", + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\"> & Pick<", { "pluginId": "core", "scope": "server", @@ -4066,7 +4175,7 @@ "label": "SanitizedAlert", "description": [], "signature": [ - "{ enabled: boolean; id: string; name: string; tags: string[]; params: Params; actions: ", + "{ id: string; name: string; tags: string[]; enabled: boolean; params: Params; actions: ", { "pluginId": "alerting", "scope": "common", @@ -4112,7 +4221,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<never>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">, \"enabled\" | \"name\" | \"tags\" | \"actions\" | \"throttle\" | \"consumer\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"notifyWhen\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" + "<never>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">, \"name\" | \"tags\" | \"enabled\" | \"actions\" | \"throttle\" | \"consumer\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"notifyWhen\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" ], "path": "x-pack/plugins/alerting/common/alert.ts", "deprecated": false, diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 32a9195f2fd1d..333c524db5e24 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -18,7 +18,7 @@ Contact [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 249 | 0 | 241 | 17 | +| 257 | 0 | 249 | 17 | ## Client diff --git a/api_docs/apm.json b/api_docs/apm.json index 8b43370097091..f0c84d9974c31 100644 --- a/api_docs/apm.json +++ b/api_docs/apm.json @@ -184,11 +184,11 @@ "APMPluginStartDependencies", ", unknown>, plugins: Pick<", "APMPluginSetupDependencies", - ", \"data\" | \"cloud\" | \"security\" | \"home\" | \"features\" | \"fleet\" | \"ml\" | \"actions\" | \"usageCollection\" | \"spaces\" | \"apmOss\" | \"licensing\" | \"observability\" | \"ruleRegistry\" | \"taskManager\" | \"alerting\">) => { config$: ", + ", \"data\" | \"cloud\" | \"security\" | \"home\" | \"features\" | \"fleet\" | \"ml\" | \"spaces\" | \"actions\" | \"usageCollection\" | \"licensing\" | \"observability\" | \"ruleRegistry\" | \"taskManager\" | \"alerting\">) => { config$: ", "Observable", - "<{ 'apm_oss.transactionIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.metricsIndices': string; 'apm_oss.sourcemapIndices': string; 'apm_oss.onboardingIndices': string; 'xpack.apm.serviceMapEnabled': boolean; 'xpack.apm.serviceMapFingerprintBucketSize': number; 'xpack.apm.serviceMapTraceIdBucketSize': number; 'xpack.apm.serviceMapFingerprintGlobalBucketSize': number; 'xpack.apm.serviceMapTraceIdGlobalBucketSize': number; 'xpack.apm.serviceMapMaxTracesPerRequest': number; 'xpack.apm.ui.enabled': boolean; 'xpack.apm.ui.maxTraceItems': number; 'xpack.apm.ui.transactionGroupBucketSize': number; 'xpack.apm.autocreateApmIndexPattern': boolean; 'xpack.apm.telemetryCollectionEnabled': boolean; 'xpack.apm.searchAggregatedTransactions': ", + "<Readonly<{} & { enabled: boolean; indices: Readonly<{} & { error: string; metric: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; autocreateApmIndexPattern: boolean; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; 'xpack.apm.metricsInterval': number; 'xpack.apm.agent.migrations.enabled': boolean; }>; getApmIndices: () => Promise<", + "; telemetryCollectionEnabled: boolean; metricsInterval: number; profilingEnabled: boolean; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>>; getApmIndices: () => Promise<", "ApmIndicesConfig", ">; createApmEventClient: ({ request, context, debug, }: { debug?: boolean | undefined; request: ", { @@ -248,7 +248,7 @@ "signature": [ "Pick<", "APMPluginSetupDependencies", - ", \"data\" | \"cloud\" | \"security\" | \"home\" | \"features\" | \"fleet\" | \"ml\" | \"actions\" | \"usageCollection\" | \"spaces\" | \"apmOss\" | \"licensing\" | \"observability\" | \"ruleRegistry\" | \"taskManager\" | \"alerting\">" + ", \"data\" | \"cloud\" | \"security\" | \"home\" | \"features\" | \"fleet\" | \"ml\" | \"spaces\" | \"actions\" | \"usageCollection\" | \"licensing\" | \"observability\" | \"ruleRegistry\" | \"taskManager\" | \"alerting\">" ], "path": "x-pack/plugins/apm/server/plugin.ts", "deprecated": false, @@ -320,59 +320,7 @@ "initialIsOpen": false } ], - "functions": [ - { - "parentPluginId": "apm", - "id": "def-server.mergeConfigs", - "type": "Function", - "tags": [], - "label": "mergeConfigs", - "description": [], - "signature": [ - "(apmOssConfig: Readonly<{} & { enabled: boolean; transactionIndices: string; spanIndices: string; errorIndices: string; metricsIndices: string; sourcemapIndices: string; onboardingIndices: string; indexPattern: string; fleetMode: boolean; }>, apmConfig: Readonly<{} & { enabled: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; autocreateApmIndexPattern: boolean; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", - "SearchAggregatedTransactionSetting", - "; telemetryCollectionEnabled: boolean; metricsInterval: number; profilingEnabled: boolean; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>) => { 'apm_oss.transactionIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.metricsIndices': string; 'apm_oss.sourcemapIndices': string; 'apm_oss.onboardingIndices': string; 'xpack.apm.serviceMapEnabled': boolean; 'xpack.apm.serviceMapFingerprintBucketSize': number; 'xpack.apm.serviceMapTraceIdBucketSize': number; 'xpack.apm.serviceMapFingerprintGlobalBucketSize': number; 'xpack.apm.serviceMapTraceIdGlobalBucketSize': number; 'xpack.apm.serviceMapMaxTracesPerRequest': number; 'xpack.apm.ui.enabled': boolean; 'xpack.apm.ui.maxTraceItems': number; 'xpack.apm.ui.transactionGroupBucketSize': number; 'xpack.apm.autocreateApmIndexPattern': boolean; 'xpack.apm.telemetryCollectionEnabled': boolean; 'xpack.apm.searchAggregatedTransactions': ", - "SearchAggregatedTransactionSetting", - "; 'xpack.apm.metricsInterval': number; 'xpack.apm.agent.migrations.enabled': boolean; }" - ], - "path": "x-pack/plugins/apm/server/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "apm", - "id": "def-server.mergeConfigs.$1", - "type": "Object", - "tags": [], - "label": "apmOssConfig", - "description": [], - "signature": [ - "Readonly<{} & { enabled: boolean; transactionIndices: string; spanIndices: string; errorIndices: string; metricsIndices: string; sourcemapIndices: string; onboardingIndices: string; indexPattern: string; fleetMode: boolean; }>" - ], - "path": "x-pack/plugins/apm/server/index.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "apm", - "id": "def-server.mergeConfigs.$2", - "type": "Object", - "tags": [], - "label": "apmConfig", - "description": [], - "signature": [ - "Readonly<{} & { enabled: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; autocreateApmIndexPattern: boolean; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", - "SearchAggregatedTransactionSetting", - "; telemetryCollectionEnabled: boolean; metricsInterval: number; profilingEnabled: boolean; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>" - ], - "path": "x-pack/plugins/apm/server/index.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], + "functions": [], "interfaces": [ { "parentPluginId": "apm", @@ -440,9 +388,9 @@ "label": "config", "description": [], "signature": [ - "{ 'apm_oss.transactionIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.metricsIndices': string; 'apm_oss.sourcemapIndices': string; 'apm_oss.onboardingIndices': string; 'xpack.apm.serviceMapEnabled': boolean; 'xpack.apm.serviceMapFingerprintBucketSize': number; 'xpack.apm.serviceMapTraceIdBucketSize': number; 'xpack.apm.serviceMapFingerprintGlobalBucketSize': number; 'xpack.apm.serviceMapTraceIdGlobalBucketSize': number; 'xpack.apm.serviceMapMaxTracesPerRequest': number; 'xpack.apm.ui.enabled': boolean; 'xpack.apm.ui.maxTraceItems': number; 'xpack.apm.ui.transactionGroupBucketSize': number; 'xpack.apm.autocreateApmIndexPattern': boolean; 'xpack.apm.telemetryCollectionEnabled': boolean; 'xpack.apm.searchAggregatedTransactions': ", + "{ readonly enabled: boolean; readonly indices: Readonly<{} & { error: string; metric: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly autocreateApmIndexPattern: boolean; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; 'xpack.apm.metricsInterval': number; 'xpack.apm.agent.migrations.enabled': boolean; }" + "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly profilingEnabled: boolean; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" ], "path": "x-pack/plugins/apm/server/routes/typings.ts", "deprecated": false @@ -535,15 +483,7 @@ "section": "def-server.PluginStartContract", "text": "PluginStartContract" }, - ">; }; apmOss: { setup: ", - { - "pluginId": "apmOss", - "scope": "server", - "docId": "kibApmOssPluginApi", - "section": "def-server.APMOSSPluginSetup", - "text": "APMOSSPluginSetup" - }, - "; start: () => Promise<undefined>; }; licensing: { setup: ", + ">; }; licensing: { setup: ", { "pluginId": "licensing", "scope": "server", @@ -655,7 +595,23 @@ }, ">; } | undefined; ml?: { setup: ", "SharedServices", - "; start: () => Promise<void>; } | undefined; actions?: { setup: ", + "; start: () => Promise<void>; } | undefined; spaces?: { setup: ", + { + "pluginId": "spaces", + "scope": "server", + "docId": "kibSpacesPluginApi", + "section": "def-server.SpacesPluginSetup", + "text": "SpacesPluginSetup" + }, + "; start: () => Promise<", + { + "pluginId": "spaces", + "scope": "server", + "docId": "kibSpacesPluginApi", + "section": "def-server.SpacesPluginStart", + "text": "SpacesPluginStart" + }, + ">; } | undefined; actions?: { setup: ", { "pluginId": "actions", "scope": "server", @@ -679,23 +635,7 @@ "section": "def-server.UsageCollectionSetup", "text": "UsageCollectionSetup" }, - "; start: () => Promise<undefined>; } | undefined; spaces?: { setup: ", - { - "pluginId": "spaces", - "scope": "server", - "docId": "kibSpacesPluginApi", - "section": "def-server.SpacesPluginSetup", - "text": "SpacesPluginSetup" - }, - "; start: () => Promise<", - { - "pluginId": "spaces", - "scope": "server", - "docId": "kibSpacesPluginApi", - "section": "def-server.SpacesPluginStart", - "text": "SpacesPluginStart" - }, - ">; } | undefined; taskManager?: { setup: ", + "; start: () => Promise<undefined>; } | undefined; taskManager?: { setup: ", { "pluginId": "taskManager", "scope": "server", @@ -825,9 +765,23 @@ "label": "APMConfig", "description": [], "signature": [ - "{ 'apm_oss.transactionIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.metricsIndices': string; 'apm_oss.sourcemapIndices': string; 'apm_oss.onboardingIndices': string; 'xpack.apm.serviceMapEnabled': boolean; 'xpack.apm.serviceMapFingerprintBucketSize': number; 'xpack.apm.serviceMapTraceIdBucketSize': number; 'xpack.apm.serviceMapFingerprintGlobalBucketSize': number; 'xpack.apm.serviceMapTraceIdGlobalBucketSize': number; 'xpack.apm.serviceMapMaxTracesPerRequest': number; 'xpack.apm.ui.enabled': boolean; 'xpack.apm.ui.maxTraceItems': number; 'xpack.apm.ui.transactionGroupBucketSize': number; 'xpack.apm.autocreateApmIndexPattern': boolean; 'xpack.apm.telemetryCollectionEnabled': boolean; 'xpack.apm.searchAggregatedTransactions': ", + "{ readonly enabled: boolean; readonly indices: Readonly<{} & { error: string; metric: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly autocreateApmIndexPattern: boolean; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; 'xpack.apm.metricsInterval': number; 'xpack.apm.agent.migrations.enabled': boolean; }" + "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly profilingEnabled: boolean; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" + ], + "path": "x-pack/plugins/apm/server/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "apm", + "id": "def-server.ApmIndicesConfigName", + "type": "Type", + "tags": [], + "label": "ApmIndicesConfigName", + "description": [], + "signature": [ + "\"error\" | \"metric\" | \"span\" | \"transaction\" | \"sourcemap\" | \"onboarding\"" ], "path": "x-pack/plugins/apm/server/index.ts", "deprecated": false, @@ -4046,7 +4000,7 @@ "section": "def-server.APMRouteHandlerResources", "text": "APMRouteHandlerResources" }, - ", { apmIndexSettings: { configurationName: \"apm_oss.sourcemapIndices\" | \"apm_oss.errorIndices\" | \"apm_oss.onboardingIndices\" | \"apm_oss.spanIndices\" | \"apm_oss.transactionIndices\" | \"apm_oss.metricsIndices\" | \"apmAgentConfigurationIndex\" | \"apmCustomLinkIndex\"; defaultValue: string; savedValue: string | undefined; }[]; }, ", + ", { apmIndexSettings: { configurationName: \"error\" | \"metric\" | \"span\" | \"transaction\" | \"sourcemap\" | \"onboarding\"; defaultValue: string; savedValue: string | undefined; }[]; }, ", "APMRouteCreateOptions", ">; } & { \"GET /internal/apm/settings/apm-indices\": ", { @@ -4080,19 +4034,7 @@ "TypeC", "<{ body: ", "PartialC", - "<{ 'apm_oss.sourcemapIndices': ", - "StringC", - "; 'apm_oss.errorIndices': ", - "StringC", - "; 'apm_oss.onboardingIndices': ", - "StringC", - "; 'apm_oss.spanIndices': ", - "StringC", - "; 'apm_oss.transactionIndices': ", - "StringC", - "; 'apm_oss.metricsIndices': ", - "StringC", - "; }>; }>, ", + "<SaveApmIndicesBodySchema>; }>, ", { "pluginId": "apm", "scope": "server", @@ -4959,22 +4901,6 @@ "path": "x-pack/plugins/apm/server/routes/get_global_apm_server_route_repository.ts", "deprecated": false, "initialIsOpen": false - }, - { - "parentPluginId": "apm", - "id": "def-server.APMXPackConfig", - "type": "Type", - "tags": [], - "label": "APMXPackConfig", - "description": [], - "signature": [ - "{ readonly enabled: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly autocreateApmIndexPattern: boolean; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", - "SearchAggregatedTransactionSetting", - "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly profilingEnabled: boolean; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" - ], - "path": "x-pack/plugins/apm/server/index.ts", - "deprecated": false, - "initialIsOpen": false } ], "objects": [], @@ -4997,9 +4923,9 @@ "description": [], "signature": [ "Observable", - "<{ 'apm_oss.transactionIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.metricsIndices': string; 'apm_oss.sourcemapIndices': string; 'apm_oss.onboardingIndices': string; 'xpack.apm.serviceMapEnabled': boolean; 'xpack.apm.serviceMapFingerprintBucketSize': number; 'xpack.apm.serviceMapTraceIdBucketSize': number; 'xpack.apm.serviceMapFingerprintGlobalBucketSize': number; 'xpack.apm.serviceMapTraceIdGlobalBucketSize': number; 'xpack.apm.serviceMapMaxTracesPerRequest': number; 'xpack.apm.ui.enabled': boolean; 'xpack.apm.ui.maxTraceItems': number; 'xpack.apm.ui.transactionGroupBucketSize': number; 'xpack.apm.autocreateApmIndexPattern': boolean; 'xpack.apm.telemetryCollectionEnabled': boolean; 'xpack.apm.searchAggregatedTransactions': ", + "<Readonly<{} & { enabled: boolean; indices: Readonly<{} & { error: string; metric: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; autocreateApmIndexPattern: boolean; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; 'xpack.apm.metricsInterval': number; 'xpack.apm.agent.migrations.enabled': boolean; }>" + "; telemetryCollectionEnabled: boolean; metricsInterval: number; profilingEnabled: boolean; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>>" ], "path": "x-pack/plugins/apm/server/types.ts", "deprecated": false diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index d9e53e6ec9df8..5daa09e8df84c 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -18,7 +18,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 | 37 | +| 39 | 0 | 39 | 37 | ## Client @@ -36,9 +36,6 @@ Contact [APM UI](https://github.com/orgs/elastic/teams/apm-ui) for questions reg ### Setup <DocDefinitionList data={[apmObj.server.setup]}/> -### Functions -<DocDefinitionList data={apmObj.server.functions}/> - ### Classes <DocDefinitionList data={apmObj.server.classes}/> diff --git a/api_docs/apm_oss.json b/api_docs/apm_oss.json deleted file mode 100644 index adcf164f39450..0000000000000 --- a/api_docs/apm_oss.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "id": "apmOss", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [], - "setup": { - "parentPluginId": "apmOss", - "id": "def-public.ApmOssPluginSetup", - "type": "Interface", - "tags": [], - "label": "ApmOssPluginSetup", - "description": [], - "path": "src/plugins/apm_oss/public/types.ts", - "deprecated": false, - "children": [], - "lifecycle": "setup", - "initialIsOpen": true - }, - "start": { - "parentPluginId": "apmOss", - "id": "def-public.ApmOssPluginStart", - "type": "Interface", - "tags": [], - "label": "ApmOssPluginStart", - "description": [], - "path": "src/plugins/apm_oss/public/types.ts", - "deprecated": false, - "children": [], - "lifecycle": "start", - "initialIsOpen": true - } - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [ - { - "parentPluginId": "apmOss", - "id": "def-server.APMOSSConfig", - "type": "Type", - "tags": [], - "label": "APMOSSConfig", - "description": [], - "signature": [ - "{ readonly enabled: boolean; readonly transactionIndices: string; readonly spanIndices: string; readonly errorIndices: string; readonly metricsIndices: string; readonly sourcemapIndices: string; readonly onboardingIndices: string; readonly indexPattern: string; readonly fleetMode: boolean; }" - ], - "path": "src/plugins/apm_oss/server/index.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [], - "setup": { - "parentPluginId": "apmOss", - "id": "def-server.APMOSSPluginSetup", - "type": "Interface", - "tags": [], - "label": "APMOSSPluginSetup", - "description": [], - "path": "src/plugins/apm_oss/server/plugin.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "apmOss", - "id": "def-server.APMOSSPluginSetup.config", - "type": "Object", - "tags": [], - "label": "config", - "description": [], - "signature": [ - "{ readonly enabled: boolean; readonly transactionIndices: string; readonly spanIndices: string; readonly errorIndices: string; readonly metricsIndices: string; readonly sourcemapIndices: string; readonly onboardingIndices: string; readonly indexPattern: string; readonly fleetMode: boolean; }" - ], - "path": "src/plugins/apm_oss/server/plugin.ts", - "deprecated": false - }, - { - "parentPluginId": "apmOss", - "id": "def-server.APMOSSPluginSetup.config$", - "type": "Object", - "tags": [], - "label": "config$", - "description": [], - "signature": [ - "Observable", - "<Readonly<{} & { enabled: boolean; transactionIndices: string; spanIndices: string; errorIndices: string; metricsIndices: string; sourcemapIndices: string; onboardingIndices: string; indexPattern: string; fleetMode: boolean; }>>" - ], - "path": "src/plugins/apm_oss/server/plugin.ts", - "deprecated": false - } - ], - "lifecycle": "setup", - "initialIsOpen": true - } - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/apm_oss.mdx b/api_docs/apm_oss.mdx deleted file mode 100644 index 214147f9f4690..0000000000000 --- a/api_docs/apm_oss.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -id: kibApmOssPluginApi -slug: /kibana-dev-docs/api/apmOss -title: "apmOss" -image: https://source.unsplash.com/400x175/?github -summary: API docs for the apmOss plugin -date: 2020-11-16 -tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmOss'] -warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. ---- -import apmOssObj from './apm_oss.json'; - - - -Contact [APM UI](https://github.com/orgs/elastic/teams/apm-ui) for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 6 | 0 | 6 | 0 | - -## Client - -### Setup -<DocDefinitionList data={[apmOssObj.client.setup]}/> - -### Start -<DocDefinitionList data={[apmOssObj.client.start]}/> - -## Server - -### Setup -<DocDefinitionList data={[apmOssObj.server.setup]}/> - -### Consts, variables and types -<DocDefinitionList data={apmOssObj.server.misc}/> - diff --git a/api_docs/bfetch.json b/api_docs/bfetch.json index c274b6a6d1ced..4f9f7a33ebd3f 100644 --- a/api_docs/bfetch.json +++ b/api_docs/bfetch.json @@ -238,86 +238,7 @@ } ], "enums": [], - "misc": [ - { - "parentPluginId": "bfetch", - "id": "def-server.StreamingRequestHandler", - "type": "Type", - "tags": [], - "label": "StreamingRequestHandler", - "description": [ - "\nRequest handler modified to allow to return an observable.\n\nSee {@link BfetchServerSetup.createStreamingRequestHandler} for usage example." - ], - "signature": [ - "(context: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - }, - ", request: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.KibanaRequest", - "text": "KibanaRequest" - }, - "<P, Q, B, Method>) => ", - "Observable", - "<Response> | Promise<", - "Observable", - "<Response>>" - ], - "path": "src/plugins/bfetch/server/types.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "bfetch", - "id": "def-server.StreamingRequestHandler.$1", - "type": "Object", - "tags": [], - "label": "context", - "description": [], - "signature": [ - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - } - ], - "path": "src/plugins/bfetch/server/types.ts", - "deprecated": false - }, - { - "parentPluginId": "bfetch", - "id": "def-server.StreamingRequestHandler.$2", - "type": "Object", - "tags": [], - "label": "request", - "description": [], - "signature": [ - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.KibanaRequest", - "text": "KibanaRequest" - }, - "<P, Q, B, Method>" - ], - "path": "src/plugins/bfetch/server/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], + "misc": [], "objects": [], "setup": { "parentPluginId": "bfetch", @@ -480,259 +401,6 @@ } ], "returnComment": [] - }, - { - "parentPluginId": "bfetch", - "id": "def-server.BfetchServerSetup.createStreamingRequestHandler", - "type": "Function", - "tags": [], - "label": "createStreamingRequestHandler", - "description": [ - "\nCreate a streaming request handler to be able to use an Observable to return chunked content to the client.\nThis is meant to be used with the `fetchStreaming` API of the `bfetch` client-side plugin.\n" - ], - "signature": [ - "<Response, P, Q, B, Context extends ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - }, - " = ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - }, - ", Method extends ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.RouteMethod", - "text": "RouteMethod" - }, - " = any>(streamHandler: ", - { - "pluginId": "bfetch", - "scope": "server", - "docId": "kibBfetchPluginApi", - "section": "def-server.StreamingRequestHandler", - "text": "StreamingRequestHandler" - }, - "<Response, P, Q, B, Method>) => ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.RequestHandler", - "text": "RequestHandler" - }, - "<P, Q, B, Context, Method, { custom: <T extends string | Record<string, any> | Error | { message: string | Error; attributes?: Record<string, any> | undefined; } | Buffer | ", - "Stream", - " | undefined>(options: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.CustomHttpResponseOptions", - "text": "CustomHttpResponseOptions" - }, - "<T>) => ", - "KibanaResponse", - "<T>; badRequest: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ErrorHttpResponseOptions", - "text": "ErrorHttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">; unauthorized: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ErrorHttpResponseOptions", - "text": "ErrorHttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">; forbidden: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ErrorHttpResponseOptions", - "text": "ErrorHttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">; notFound: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ErrorHttpResponseOptions", - "text": "ErrorHttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">; conflict: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ErrorHttpResponseOptions", - "text": "ErrorHttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">; customError: (options: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.CustomHttpResponseOptions", - "text": "CustomHttpResponseOptions" - }, - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">) => ", - "KibanaResponse", - "<", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.ResponseError", - "text": "ResponseError" - }, - ">; redirected: (options: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.RedirectResponseOptions", - "text": "RedirectResponseOptions" - }, - ") => ", - "KibanaResponse", - "<string | Record<string, any> | Buffer | ", - "Stream", - ">; ok: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.HttpResponseOptions", - "text": "HttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<string | Record<string, any> | Buffer | ", - "Stream", - ">; accepted: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.HttpResponseOptions", - "text": "HttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<string | Record<string, any> | Buffer | ", - "Stream", - ">; noContent: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreHttpPluginApi", - "section": "def-server.HttpResponseOptions", - "text": "HttpResponseOptions" - }, - ") => ", - "KibanaResponse", - "<undefined>; }>" - ], - "path": "src/plugins/bfetch/server/plugin.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "bfetch", - "id": "def-server.BfetchServerSetup.createStreamingRequestHandler.$1", - "type": "Function", - "tags": [], - "label": "streamHandler", - "description": [], - "signature": [ - { - "pluginId": "bfetch", - "scope": "server", - "docId": "kibBfetchPluginApi", - "section": "def-server.StreamingRequestHandler", - "text": "StreamingRequestHandler" - }, - "<Response, P, Q, B, Method>" - ], - "path": "src/plugins/bfetch/server/plugin.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] } ], "lifecycle": "setup", @@ -1024,6 +692,65 @@ } ], "functions": [ + { + "parentPluginId": "bfetch", + "id": "def-common.appendQueryParam", + "type": "Function", + "tags": [], + "label": "appendQueryParam", + "description": [], + "signature": [ + "(url: string, key: string, value: string) => string" + ], + "path": "src/plugins/bfetch/common/util/query_params.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "bfetch", + "id": "def-common.appendQueryParam.$1", + "type": "string", + "tags": [], + "label": "url", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/bfetch/common/util/query_params.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "bfetch", + "id": "def-common.appendQueryParam.$2", + "type": "string", + "tags": [], + "label": "key", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/bfetch/common/util/query_params.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "bfetch", + "id": "def-common.appendQueryParam.$3", + "type": "string", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/bfetch/common/util/query_params.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "bfetch", "id": "def-common.createBatchedFunction", diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 25e77b7731790..ca32afc24e166 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 77 | 1 | 66 | 2 | +| 76 | 1 | 67 | 2 | ## Client @@ -42,9 +42,6 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services ### Interfaces <DocDefinitionList data={bfetchObj.server.interfaces}/> -### Consts, variables and types -<DocDefinitionList data={bfetchObj.server.misc}/> - ## Common ### Functions diff --git a/api_docs/cases.json b/api_docs/cases.json index 062235d8ed679..c35220cda3c66 100644 --- a/api_docs/cases.json +++ b/api_docs/cases.json @@ -2948,7 +2948,7 @@ "label": "action", "description": [], "signature": [ - "\"add\" | \"delete\" | \"create\" | \"update\" | \"push-to-service\"" + "\"add\" | \"create\" | \"delete\" | \"update\" | \"push-to-service\"" ], "path": "x-pack/plugins/cases/common/ui/types.ts", "deprecated": false @@ -4964,6 +4964,26 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "cases", + "id": "def-common.CaseActionConnector", + "type": "Type", + "tags": [], + "label": "CaseActionConnector", + "description": [], + "signature": [ + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ActionResult", + "text": "ActionResult" + } + ], + "path": "x-pack/plugins/cases/common/ui/types.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "cases", "id": "def-common.CaseAttributes", @@ -6776,7 +6796,7 @@ "label": "CaseUserActionAttributes", "description": [], "signature": [ - "{ action_field: (\"status\" | \"title\" | \"description\" | \"tags\" | \"comment\" | \"settings\" | \"owner\" | \"connector\" | \"pushed\" | \"sub_case\")[]; action: \"add\" | \"delete\" | \"create\" | \"update\" | \"push-to-service\"; action_at: string; action_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; new_value: string | null; old_value: string | null; owner: string; }" + "{ action_field: (\"status\" | \"title\" | \"description\" | \"tags\" | \"comment\" | \"settings\" | \"owner\" | \"connector\" | \"pushed\" | \"sub_case\")[]; action: \"add\" | \"create\" | \"delete\" | \"update\" | \"push-to-service\"; action_at: string; action_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; new_value: string | null; old_value: string | null; owner: string; }" ], "path": "x-pack/plugins/cases/common/api/cases/user_actions.ts", "deprecated": false, @@ -6852,7 +6872,7 @@ "label": "CaseUserActionResponse", "description": [], "signature": [ - "{ action_field: (\"status\" | \"title\" | \"description\" | \"tags\" | \"comment\" | \"settings\" | \"owner\" | \"connector\" | \"pushed\" | \"sub_case\")[]; action: \"add\" | \"delete\" | \"create\" | \"update\" | \"push-to-service\"; action_at: string; action_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; new_value: string | null; old_value: string | null; owner: string; } & { action_id: string; case_id: string; comment_id: string | null; new_val_connector_id: string | null; old_val_connector_id: string | null; } & { sub_case_id?: string | undefined; }" + "{ action_field: (\"status\" | \"title\" | \"description\" | \"tags\" | \"comment\" | \"settings\" | \"owner\" | \"connector\" | \"pushed\" | \"sub_case\")[]; action: \"add\" | \"create\" | \"delete\" | \"update\" | \"push-to-service\"; action_at: string; action_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; new_value: string | null; old_value: string | null; owner: string; } & { action_id: string; case_id: string; comment_id: string | null; new_val_connector_id: string | null; old_val_connector_id: string | null; } & { sub_case_id?: string | undefined; }" ], "path": "x-pack/plugins/cases/common/api/cases/user_actions.ts", "deprecated": false, @@ -6866,7 +6886,7 @@ "label": "CaseUserActionsResponse", "description": [], "signature": [ - "({ action_field: (\"status\" | \"title\" | \"description\" | \"tags\" | \"comment\" | \"settings\" | \"owner\" | \"connector\" | \"pushed\" | \"sub_case\")[]; action: \"add\" | \"delete\" | \"create\" | \"update\" | \"push-to-service\"; action_at: string; action_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; new_value: string | null; old_value: string | null; owner: string; } & { action_id: string; case_id: string; comment_id: string | null; new_val_connector_id: string | null; old_val_connector_id: string | null; } & { sub_case_id?: string | undefined; })[]" + "({ action_field: (\"status\" | \"title\" | \"description\" | \"tags\" | \"comment\" | \"settings\" | \"owner\" | \"connector\" | \"pushed\" | \"sub_case\")[]; action: \"add\" | \"create\" | \"delete\" | \"update\" | \"push-to-service\"; action_at: string; action_by: { email: string | null | undefined; full_name: string | null | undefined; username: string | null | undefined; }; new_value: string | null; old_value: string | null; owner: string; } & { action_id: string; case_id: string; comment_id: string | null; new_val_connector_id: string | null; old_val_connector_id: string | null; } & { sub_case_id?: string | undefined; })[]" ], "path": "x-pack/plugins/cases/common/api/cases/user_actions.ts", "deprecated": false, @@ -8573,7 +8593,7 @@ "label": "UserAction", "description": [], "signature": [ - "\"add\" | \"delete\" | \"create\" | \"update\" | \"push-to-service\"" + "\"add\" | \"create\" | \"delete\" | \"update\" | \"push-to-service\"" ], "path": "x-pack/plugins/cases/common/api/cases/user_actions.ts", "deprecated": false, diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 4d2c96b89917f..9400133d89bda 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -18,7 +18,7 @@ Contact [Security Solution Threat Hunting](https://github.com/orgs/elastic/teams | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 475 | 0 | 431 | 14 | +| 476 | 0 | 432 | 14 | ## Client diff --git a/api_docs/charts.json b/api_docs/charts.json index 83a2a93df42a1..d6ad087ad1601 100644 --- a/api_docs/charts.json +++ b/api_docs/charts.json @@ -4266,4 +4266,4 @@ } ] } -} +} \ No newline at end of file diff --git a/api_docs/core.json b/api_docs/core.json index c288037b4486d..e09641530635e 100644 --- a/api_docs/core.json +++ b/api_docs/core.json @@ -1603,7 +1603,7 @@ "label": "links", "description": [], "signature": [ - "{ readonly settings: string; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly enterpriseSearch: { readonly base: string; readonly appSearchBase: string; readonly workplaceSearchBase: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite_missing_bucket: string; readonly date_histogram: string; readonly date_range: string; readonly date_format_pattern: string; readonly filter: string; readonly filters: string; readonly geohash_grid: string; readonly histogram: string; readonly ip_range: string; readonly range: string; readonly significant_terms: string; readonly terms: string; readonly avg: string; readonly avg_bucket: string; readonly max_bucket: string; readonly min_bucket: string; readonly sum_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative_sum: string; readonly derivative: string; readonly geo_bounds: string; readonly geo_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving_avg: string; readonly percentile_ranks: string; readonly serial_diff: string; readonly std_dev: string; readonly sum: string; readonly top_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: string; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; readonly autocompleteChanges: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Record<string, string>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: Record<string, string>; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; }" + "{ readonly settings: string; readonly elasticStackGetStarted: string; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly enterpriseSearch: { readonly base: string; readonly appSearchBase: string; readonly workplaceSearchBase: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite_missing_bucket: string; readonly date_histogram: string; readonly date_range: string; readonly date_format_pattern: string; readonly filter: string; readonly filters: string; readonly geohash_grid: string; readonly histogram: string; readonly ip_range: string; readonly range: string; readonly significant_terms: string; readonly terms: string; readonly avg: string; readonly avg_bucket: string; readonly max_bucket: string; readonly min_bucket: string; readonly sum_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative_sum: string; readonly derivative: string; readonly geo_bounds: string; readonly geo_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving_avg: string; readonly percentile_ranks: string; readonly serial_diff: string; readonly std_dev: string; readonly sum: string; readonly top_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: string; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; readonly autocompleteChanges: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Record<string, string>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: Record<string, string>; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; }" ], "path": "src/core/public/doc_links/doc_links_service.ts", "deprecated": false @@ -2079,7 +2079,7 @@ "signature": [ "() => Readonly<Record<string, Pick<", "UiSettingsParams", - "<unknown>, \"type\" | \"options\" | \"description\" | \"name\" | \"order\" | \"value\" | \"category\" | \"optionLabels\" | \"requiresPageReload\" | \"readonly\" | \"sensitive\" | \"deprecation\" | \"metric\"> & ", + "<unknown>, \"type\" | \"description\" | \"name\" | \"options\" | \"order\" | \"value\" | \"category\" | \"optionLabels\" | \"requiresPageReload\" | \"readonly\" | \"sensitive\" | \"deprecation\" | \"metric\"> & ", "UserProvidedValues", "<any>>>" ], @@ -3265,7 +3265,7 @@ "label": "buttonColor", "description": [], "signature": [ - "\"warning\" | \"text\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"secondary\" | \"ghost\" | undefined" + "\"text\" | \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"secondary\" | \"ghost\" | undefined" ], "path": "src/core/public/overlays/modal/modal_service.tsx", "deprecated": false @@ -6622,7 +6622,7 @@ "\nA sub-set of {@link UiSettingsParams} exposed to the client-side." ], "signature": [ - "{ type?: \"string\" | \"number\" | \"boolean\" | \"undefined\" | \"color\" | \"json\" | \"image\" | \"markdown\" | \"select\" | \"array\" | undefined; options?: string[] | undefined; description?: string | undefined; name?: string | undefined; order?: number | undefined; value?: unknown; category?: string[] | undefined; optionLabels?: Record<string, string> | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", + "{ type?: \"string\" | \"number\" | \"boolean\" | \"undefined\" | \"color\" | \"json\" | \"image\" | \"markdown\" | \"select\" | \"array\" | undefined; description?: string | undefined; name?: string | undefined; options?: string[] | undefined; order?: number | undefined; value?: unknown; category?: string[] | undefined; optionLabels?: Record<string, string> | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", "DeprecationSettings", " | undefined; metric?: { type: ", { @@ -7291,19 +7291,6 @@ "path": "src/core/server/csp/csp_config.ts", "deprecated": false }, - { - "parentPluginId": "core", - "id": "def-server.CspConfig.rules", - "type": "Array", - "tags": [], - "label": "rules", - "description": [], - "signature": [ - "string[]" - ], - "path": "src/core/server/csp/csp_config.ts", - "deprecated": false - }, { "parentPluginId": "core", "id": "def-server.CspConfig.strict", @@ -9627,7 +9614,7 @@ "corrective action needed to fix this deprecation." ], "signature": [ - "{ api?: { path: string; method: \"PUT\" | \"POST\"; body?: { [key: string]: any; } | undefined; } | undefined; manualSteps: string[]; }" + "{ api?: { path: string; method: \"PUT\" | \"POST\"; body?: { [key: string]: any; } | undefined; omitContextFromBody?: boolean | undefined; } | undefined; manualSteps: string[]; }" ], "path": "src/core/server/deprecations/types.ts", "deprecated": false @@ -10345,7 +10332,7 @@ "Headers used for authentication against Elasticsearch" ], "signature": [ - "{ accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; date?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; from?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; warning?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ from?: string | string[] | undefined; date?: string | string[] | undefined; origin?: string | string[] | undefined; range?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "src/core/server/elasticsearch/types.ts", "deprecated": false @@ -10390,25 +10377,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -10466,7 +10435,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -10530,6 +10507,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -11334,7 +11321,7 @@ "\nHTTP Headers with additional information about response." ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" ], "path": "src/core/server/http_resources/types.ts", "deprecated": false @@ -11646,7 +11633,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -12454,21 +12441,6 @@ "path": "src/core/server/csp/csp_config.ts", "deprecated": false, "children": [ - { - "parentPluginId": "core", - "id": "def-server.ICspConfig.rules", - "type": "Array", - "tags": [], - "label": "rules", - "description": [ - "\nThe CSP rules used for Kibana." - ], - "signature": [ - "string[]" - ], - "path": "src/core/server/csp/csp_config.ts", - "deprecated": false - }, { "parentPluginId": "core", "id": "def-server.ICspConfig.strict", @@ -12500,7 +12472,7 @@ "tags": [], "label": "disableEmbedding", "description": [ - "\nWhether or not embedding (using iframes) should be allowed by the CSP. If embedding is disabled *and* no custom rules have been\ndefined, a restrictive 'frame-ancestors' rule will be added to the default CSP rules." + "\nWhether or not embedding (using iframes) should be allowed by the CSP. If embedding is disabled, a restrictive 'frame-ancestors' rule will be added to the default CSP rules." ], "path": "src/core/server/csp/csp_config.ts", "deprecated": false @@ -12858,7 +12830,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -12883,7 +12855,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -12923,7 +12895,7 @@ "signature": [ "() => Readonly<Record<string, Pick<", "UiSettingsParams", - "<unknown>, \"type\" | \"options\" | \"description\" | \"name\" | \"order\" | \"value\" | \"category\" | \"optionLabels\" | \"requiresPageReload\" | \"readonly\" | \"sensitive\" | \"deprecation\" | \"metric\">>>" + "<unknown>, \"type\" | \"description\" | \"name\" | \"options\" | \"order\" | \"value\" | \"category\" | \"optionLabels\" | \"requiresPageReload\" | \"readonly\" | \"sensitive\" | \"deprecation\" | \"metric\">>>" ], "path": "src/core/server/ui_settings/types.ts", "deprecated": false, @@ -15382,7 +15354,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; typeRegistry: Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; typeRegistry: Pick<", { "pluginId": "core", "scope": "server", @@ -15406,7 +15378,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; getExporter: (client: Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; getExporter: (client: Pick<", { "pluginId": "core", "scope": "server", @@ -15414,7 +15386,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", { "pluginId": "core", "scope": "server", @@ -15430,7 +15402,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", { "pluginId": "core", "scope": "server", @@ -16611,7 +16583,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => ", { "pluginId": "core", "scope": "server", @@ -16639,7 +16611,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/core/server/ui_settings/types.ts", "deprecated": false, @@ -17157,7 +17129,7 @@ "label": "EcsEventCategory", "description": [], "signature": [ - "\"host\" | \"network\" | \"web\" | \"database\" | \"package\" | \"session\" | \"file\" | \"registry\" | \"process\" | \"authentication\" | \"configuration\" | \"driver\" | \"iam\" | \"intrusion_detection\" | \"malware\"" + "\"network\" | \"web\" | \"database\" | \"package\" | \"host\" | \"session\" | \"file\" | \"registry\" | \"process\" | \"authentication\" | \"configuration\" | \"driver\" | \"iam\" | \"intrusion_detection\" | \"malware\"" ], "path": "node_modules/@kbn/logging/target_types/ecs/event.d.ts", "deprecated": false, @@ -17199,7 +17171,7 @@ "label": "EcsEventType", "description": [], "signature": [ - "\"start\" | \"connection\" | \"end\" | \"user\" | \"error\" | \"info\" | \"group\" | \"protocol\" | \"access\" | \"admin\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" + "\"start\" | \"end\" | \"user\" | \"error\" | \"info\" | \"connection\" | \"group\" | \"protocol\" | \"access\" | \"admin\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" ], "path": "node_modules/@kbn/logging/target_types/ecs/event.d.ts", "deprecated": false, @@ -17217,7 +17189,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -18364,7 +18336,7 @@ "\nA sub-set of {@link UiSettingsParams} exposed to the client-side." ], "signature": [ - "{ type?: \"string\" | \"number\" | \"boolean\" | \"undefined\" | \"color\" | \"json\" | \"image\" | \"markdown\" | \"select\" | \"array\" | undefined; options?: string[] | undefined; description?: string | undefined; name?: string | undefined; order?: number | undefined; value?: unknown; category?: string[] | undefined; optionLabels?: Record<string, string> | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", + "{ type?: \"string\" | \"number\" | \"boolean\" | \"undefined\" | \"color\" | \"json\" | \"image\" | \"markdown\" | \"select\" | \"array\" | undefined; description?: string | undefined; name?: string | undefined; options?: string[] | undefined; order?: number | undefined; value?: unknown; category?: string[] | undefined; optionLabels?: Record<string, string> | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", "DeprecationSettings", " | undefined; metric?: { type: ", { diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 018a9f1beda6c..11a95ef59976f 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2300 | 27 | 1019 | 29 | +| 2298 | 27 | 1018 | 29 | ## Client diff --git a/api_docs/core_application.mdx b/api_docs/core_application.mdx index 1c01073421f69..78431e5a91867 100644 --- a/api_docs/core_application.mdx +++ b/api_docs/core_application.mdx @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2300 | 27 | 1019 | 29 | +| 2298 | 27 | 1018 | 29 | ## Client diff --git a/api_docs/core_chrome.json b/api_docs/core_chrome.json index e2404c6b386fc..604ce27aa3abe 100644 --- a/api_docs/core_chrome.json +++ b/api_docs/core_chrome.json @@ -1934,7 +1934,7 @@ "description": [], "signature": [ "CommonProps", - " & { text: React.ReactNode; href?: string | undefined; onClick?: ((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) | undefined; truncate?: boolean | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"page\" | \"time\" | \"true\" | \"false\" | \"step\" | undefined; }" + " & { text: React.ReactNode; href?: string | undefined; onClick?: ((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) | undefined; truncate?: boolean | undefined; 'aria-current'?: boolean | \"date\" | \"page\" | \"time\" | \"true\" | \"false\" | \"step\" | \"location\" | undefined; }" ], "path": "src/core/public/chrome/types.ts", "deprecated": false, diff --git a/api_docs/core_chrome.mdx b/api_docs/core_chrome.mdx index 18244445385ca..305f1041a0923 100644 --- a/api_docs/core_chrome.mdx +++ b/api_docs/core_chrome.mdx @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2300 | 27 | 1019 | 29 | +| 2298 | 27 | 1018 | 29 | ## Client diff --git a/api_docs/core_http.json b/api_docs/core_http.json index 94ee961f265b7..285e246099952 100644 --- a/api_docs/core_http.json +++ b/api_docs/core_http.json @@ -2286,7 +2286,7 @@ "\nReadonly copy of incoming request headers." ], "signature": [ - "{ accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; date?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; from?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; warning?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ from?: string | string[] | undefined; date?: string | string[] | undefined; origin?: string | string[] | undefined; range?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "src/core/server/http/router/request.ts", "deprecated": false @@ -2697,7 +2697,7 @@ "\nHeaders to attach for auth redirect.\nMust include \"location\" header" ], "signature": [ - "({ location: string; } & Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]>) | ({ location: string; } & Record<string, string | string[]>)" + "({ location: string; } & Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]>) | ({ location: string; } & Record<string, string | string[]>)" ], "path": "src/core/server/http/lifecycle/auth.ts", "deprecated": false @@ -2863,7 +2863,7 @@ "\nRedirects user to another location to complete authentication when authRequired: true\nAllows user to access a resource without redirection when authRequired: 'optional'" ], "signature": [ - "(headers: ({ location: string; } & Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]>) | ({ location: string; } & Record<string, string | string[]>)) => ", + "(headers: ({ location: string; } & Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]>) | ({ location: string; } & Record<string, string | string[]>)) => ", { "pluginId": "core", "scope": "server", @@ -2883,7 +2883,7 @@ "label": "headers", "description": [], "signature": [ - "({ location: string; } & Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]>) | ({ location: string; } & Record<string, string | string[]>)" + "({ location: string; } & Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]>) | ({ location: string; } & Record<string, string | string[]>)" ], "path": "src/core/server/http/lifecycle/auth.ts", "deprecated": false, @@ -2942,7 +2942,7 @@ "HTTP Headers with additional information about response" ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" ], "path": "src/core/server/http/router/response.ts", "deprecated": false @@ -3012,7 +3012,7 @@ "HTTP Headers with additional information about response" ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" ], "path": "src/core/server/http/router/response.ts", "deprecated": false @@ -3172,7 +3172,7 @@ "HTTP Headers with additional information about response" ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" ], "path": "src/core/server/http/router/response.ts", "deprecated": false @@ -7505,7 +7505,7 @@ "additional headers to attach to the response" ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" ], "path": "src/core/server/http/lifecycle/on_pre_response.ts", "deprecated": false @@ -7560,7 +7560,7 @@ "additional headers to attach to the response" ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]> | undefined" ], "path": "src/core/server/http/lifecycle/on_pre_response.ts", "deprecated": false @@ -9130,7 +9130,7 @@ "\nSet of HTTP methods changing the state of the server." ], "signature": [ - "\"post\" | \"put\" | \"delete\" | \"patch\"" + "\"delete\" | \"post\" | \"put\" | \"patch\"" ], "path": "src/core/server/http/router/route.ts", "deprecated": false, @@ -9252,7 +9252,7 @@ "\nHttp request headers to read." ], "signature": [ - "{ accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; date?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; from?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; warning?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ from?: string | string[] | undefined; date?: string | string[] | undefined; origin?: string | string[] | undefined; range?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "src/core/server/http/router/headers.ts", "deprecated": false, @@ -9595,7 +9595,7 @@ "\nSet of well-known HTTP headers." ], "signature": [ - "\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\"" + "\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\"" ], "path": "src/core/server/http/router/headers.ts", "deprecated": false, @@ -11965,7 +11965,7 @@ "\nHttp response headers to set." ], "signature": [ - "Record<\"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"date\" | \"expect\" | \"expires\" | \"forwarded\" | \"from\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"location\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"warning\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]>" + "Record<\"from\" | \"date\" | \"origin\" | \"range\" | \"warning\" | \"location\" | \"allow\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record<string, string | string[]>" ], "path": "src/core/server/http/router/headers.ts", "deprecated": false, @@ -11997,7 +11997,7 @@ "\nThe set of common HTTP methods supported by Kibana routing." ], "signature": [ - "\"get\" | \"options\" | \"post\" | \"put\" | \"delete\" | \"patch\"" + "\"options\" | \"delete\" | \"get\" | \"post\" | \"put\" | \"patch\"" ], "path": "src/core/server/http/router/route.ts", "deprecated": false, @@ -12638,7 +12638,7 @@ "\nSet of HTTP methods not changing the state of the server." ], "signature": [ - "\"get\" | \"options\"" + "\"options\" | \"get\"" ], "path": "src/core/server/http/router/route.ts", "deprecated": false, diff --git a/api_docs/core_http.mdx b/api_docs/core_http.mdx index ae5747c711b97..d0f9967052fba 100644 --- a/api_docs/core_http.mdx +++ b/api_docs/core_http.mdx @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2300 | 27 | 1019 | 29 | +| 2298 | 27 | 1018 | 29 | ## Client diff --git a/api_docs/core_saved_objects.json b/api_docs/core_saved_objects.json index 91af1d2465c3d..9fbd488168085 100644 --- a/api_docs/core_saved_objects.json +++ b/api_docs/core_saved_objects.json @@ -847,7 +847,7 @@ "section": "def-public.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"bulkUpdate\">" + ", \"create\" | \"bulkCreate\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"bulkUpdate\">" ], "path": "src/core/public/saved_objects/simple_saved_object.ts", "deprecated": false, @@ -1513,17 +1513,7 @@ "{@link SavedObjectsClient}" ], "signature": [ - "{ get: <T = unknown>(type: string, id: string) => Promise<", - { - "pluginId": "core", - "scope": "public", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-public.SimpleSavedObject", - "text": "SimpleSavedObject" - }, - "<T>>; delete: (type: string, id: string, options?: ", - "SavedObjectsDeleteOptions", - " | undefined) => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "public", @@ -1563,7 +1553,9 @@ "section": "def-public.SavedObjectsBatchResponse", "text": "SavedObjectsBatchResponse" }, - "<unknown>>; find: <T = unknown, A = unknown>(options: Pick<", + "<unknown>>; delete: (type: string, id: string, options?: ", + "SavedObjectsDeleteOptions", + " | undefined) => Promise<{}>; find: <T = unknown, A = unknown>(options: Pick<", { "pluginId": "core", "scope": "server", @@ -1595,7 +1587,15 @@ "section": "def-public.ResolvedSimpleSavedObject", "text": "ResolvedSimpleSavedObject" }, - "<T>[]; }>; resolve: <T = unknown>(type: string, id: string) => Promise<", + "<T>[]; }>; get: <T = unknown>(type: string, id: string) => Promise<", + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-public.SimpleSavedObject", + "text": "SimpleSavedObject" + }, + "<T>>; resolve: <T = unknown>(type: string, id: string) => Promise<", { "pluginId": "core", "scope": "public", @@ -1719,17 +1719,7 @@ "\nSavedObjectsClientContract as implemented by the {@link SavedObjectsClient}\n" ], "signature": [ - "{ get: <T = unknown>(type: string, id: string) => Promise<", - { - "pluginId": "core", - "scope": "public", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-public.SimpleSavedObject", - "text": "SimpleSavedObject" - }, - "<T>>; delete: (type: string, id: string, options?: ", - "SavedObjectsDeleteOptions", - " | undefined) => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "public", @@ -1769,7 +1759,9 @@ "section": "def-public.SavedObjectsBatchResponse", "text": "SavedObjectsBatchResponse" }, - "<unknown>>; find: <T = unknown, A = unknown>(options: Pick<", + "<unknown>>; delete: (type: string, id: string, options?: ", + "SavedObjectsDeleteOptions", + " | undefined) => Promise<{}>; find: <T = unknown, A = unknown>(options: Pick<", { "pluginId": "core", "scope": "server", @@ -1801,7 +1793,15 @@ "section": "def-public.ResolvedSimpleSavedObject", "text": "ResolvedSimpleSavedObject" }, - "<T>[]; }>; resolve: <T = unknown>(type: string, id: string) => Promise<", + "<T>[]; }>; get: <T = unknown>(type: string, id: string) => Promise<", + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-public.SimpleSavedObject", + "text": "SimpleSavedObject" + }, + "<T>>; resolve: <T = unknown>(type: string, id: string) => Promise<", { "pluginId": "core", "scope": "public", @@ -4493,25 +4493,7 @@ "label": "#savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -4569,7 +4551,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -4633,6 +4623,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -4927,25 +4927,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -5003,7 +4985,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -5067,6 +5057,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -5709,25 +5709,7 @@ "label": "#savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -5785,7 +5767,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -5849,6 +5839,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -6145,25 +6145,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -6221,7 +6203,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -6285,6 +6275,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -10596,25 +10596,7 @@ "label": "client", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -10672,7 +10654,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -10736,6 +10726,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -13862,7 +13862,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -13925,7 +13925,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -14330,7 +14330,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -14406,7 +14406,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -14471,7 +14471,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -14537,7 +14537,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", { "pluginId": "core", "scope": "server", @@ -14566,7 +14566,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -14593,7 +14593,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Pick<", { "pluginId": "core", "scope": "server", @@ -14622,7 +14622,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/core/server/saved_objects/saved_objects_service.ts", "deprecated": false, @@ -15638,25 +15638,7 @@ "\nSee {@link SavedObjectsRepository}\n" ], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -15714,7 +15696,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; deleteByNamespace: (namespace: string, options?: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; deleteByNamespace: (namespace: string, options?: ", { "pluginId": "core", "scope": "server", @@ -15786,6 +15776,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -16151,25 +16151,7 @@ "\nSaved Objects is Kibana's data persisentence mechanism allowing plugins to\nuse Elasticsearch for storing plugin state.\n\n## SavedObjectsClient errors\n\nSince the SavedObjectsClient has its hands in everything we\nare a little paranoid about the way we present errors back to\nto application code. Ideally, all errors will be either:\n\n 1. Caused by bad implementation (ie. undefined is not a function) and\n as such unpredictable\n 2. An error that has been classified and decorated appropriately\n by the decorators in {@link SavedObjectsErrorHelpers}\n\nType 1 errors are inevitable, but since all expected/handle-able errors\nshould be Type 2 the `isXYZError()` helpers exposed at\n`SavedObjectsErrorHelpers` should be used to understand and manage error\nresponses from the `SavedObjectsClient`.\n\nType 2 errors are decorated versions of the source error, so if\nthe elasticsearch client threw an error it will be decorated based\non its type. That means that rather than looking for `error.body.error.type` or\ndoing substring checks on `error.body.error.reason`, just use the helpers to\nunderstand the meaning of the error:\n\n ```js\n if (SavedObjectsErrorHelpers.isNotFoundError(error)) {\n // handle 404\n }\n\n if (SavedObjectsErrorHelpers.isNotAuthorizedError(error)) {\n // 401 handling should be automatic, but in case you wanted to know\n }\n\n // always rethrow the error unless you handle it\n throw error;\n ```\n\n### 404s from missing index\n\nFrom the perspective of application code and APIs the SavedObjectsClient is\na black box that persists objects. One of the internal details that users have\nno control over is that we use an elasticsearch index for persistence and that\nindex might be missing.\n\nAt the time of writing we are in the process of transitioning away from the\noperating assumption that the SavedObjects index is always available. Part of\nthis transition is handling errors resulting from an index missing. These used\nto trigger a 500 error in most cases, and in others cause 404s with different\nerror messages.\n\nFrom my (Spencer) perspective, a 404 from the SavedObjectsApi is a 404; The\nobject the request/call was targeting could not be found. This is why #14141\ntakes special care to ensure that 404 errors are generic and don't distinguish\nbetween index missing or document missing.\n\nSee {@link SavedObjectsClient}\nSee {@link SavedObjectsErrorHelpers}\n" ], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -16227,7 +16209,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -16291,6 +16281,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -16507,7 +16507,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/core/server/saved_objects/service/lib/scoped_client_provider.ts", "deprecated": false, @@ -16616,7 +16616,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/core/server/saved_objects/service/lib/scoped_client_provider.ts", "deprecated": false, diff --git a/api_docs/core_saved_objects.mdx b/api_docs/core_saved_objects.mdx index 5fc7bc63466b1..3d2d82e9f1821 100644 --- a/api_docs/core_saved_objects.mdx +++ b/api_docs/core_saved_objects.mdx @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2300 | 27 | 1019 | 29 | +| 2298 | 27 | 1018 | 29 | ## Client diff --git a/api_docs/custom_integrations.json b/api_docs/custom_integrations.json index 7cf82e84cfafc..3a693af2b696a 100644 --- a/api_docs/custom_integrations.json +++ b/api_docs/custom_integrations.json @@ -290,7 +290,9 @@ "type": "Interface", "tags": [], "label": "CustomIntegration", - "description": [], + "description": [ + "\nA definition of a dataintegration, which can be registered with Kibana." + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, "children": [ @@ -385,7 +387,7 @@ "label": "categories", "description": [], "signature": [ - "(\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"sample_data\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\" | \"updates_available\")[]" + "(\"custom\" | \"sample_data\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\")[]" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false @@ -393,10 +395,13 @@ { "parentPluginId": "customIntegrations", "id": "def-server.CustomIntegration.shipper", - "type": "string", + "type": "CompoundType", "tags": [], "label": "shipper", "description": [], + "signature": [ + "\"beats\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\"" + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false }, @@ -415,42 +420,6 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "customIntegrations", - "id": "def-server.IntegrationCategoryCount", - "type": "Interface", - "tags": [], - "label": "IntegrationCategoryCount", - "description": [], - "path": "src/plugins/custom_integrations/common/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "customIntegrations", - "id": "def-server.IntegrationCategoryCount.count", - "type": "number", - "tags": [], - "label": "count", - "description": [], - "path": "src/plugins/custom_integrations/common/index.ts", - "deprecated": false - }, - { - "parentPluginId": "customIntegrations", - "id": "def-server.IntegrationCategoryCount.id", - "type": "CompoundType", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"sample_data\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\" | \"updates_available\"" - ], - "path": "src/plugins/custom_integrations/common/index.ts", - "deprecated": false - } - ], - "initialIsOpen": false } ], "enums": [], @@ -461,9 +430,11 @@ "type": "Type", "tags": [], "label": "IntegrationCategory", - "description": [], + "description": [ + "\nA category applicable to an Integration." + ], "signature": [ - "\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"sample_data\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\" | \"updates_available\"" + "\"custom\" | \"sample_data\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\"" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, @@ -578,7 +549,9 @@ "type": "Interface", "tags": [], "label": "CustomIntegration", - "description": [], + "description": [ + "\nA definition of a dataintegration, which can be registered with Kibana." + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, "children": [ @@ -673,7 +646,7 @@ "label": "categories", "description": [], "signature": [ - "(\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"sample_data\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\" | \"updates_available\")[]" + "(\"custom\" | \"sample_data\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\")[]" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false @@ -681,10 +654,13 @@ { "parentPluginId": "customIntegrations", "id": "def-common.CustomIntegration.shipper", - "type": "string", + "type": "CompoundType", "tags": [], "label": "shipper", "description": [], + "signature": [ + "\"beats\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\"" + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false }, @@ -710,7 +686,9 @@ "type": "Interface", "tags": [], "label": "CustomIntegrationIcon", - "description": [], + "description": [ + "\nAn icon representing an Integration." + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, "children": [ @@ -746,7 +724,9 @@ "type": "Interface", "tags": [], "label": "IntegrationCategoryCount", - "description": [], + "description": [ + "\nAn object containing the id of an `IntegrationCategory` and the count of all Integrations in that category." + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, "children": [ @@ -768,7 +748,7 @@ "label": "id", "description": [], "signature": [ - "\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"sample_data\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\" | \"updates_available\"" + "\"custom\" | \"sample_data\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\"" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false @@ -779,15 +759,33 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "customIntegrations", + "id": "def-common.category", + "type": "Array", + "tags": [], + "label": "category", + "description": [ + "\nThe list of all available categories." + ], + "signature": [ + "(\"custom\" | \"sample_data\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\")[]" + ], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "customIntegrations", "id": "def-common.IntegrationCategory", "type": "Type", "tags": [], "label": "IntegrationCategory", - "description": [], + "description": [ + "\nA category applicable to an Integration." + ], "signature": [ - "\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"sample_data\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\" | \"updates_available\"" + "\"custom\" | \"sample_data\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | \"upload_file\" | \"language_client\"" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, @@ -842,6 +840,38 @@ "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, "initialIsOpen": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.shipper", + "type": "Array", + "tags": [], + "label": "shipper", + "description": [ + "\nThe list of all known shippers." + ], + "signature": [ + "(\"beats\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\")[]" + ], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.Shipper", + "type": "Type", + "tags": [], + "label": "Shipper", + "description": [ + "\nA shipper-- an internal or external system capable of storing data in ES/Kibana-- applicable to an Integration." + ], + "signature": [ + "\"beats\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\"" + ], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false, + "initialIsOpen": false } ], "objects": [ @@ -851,7 +881,9 @@ "type": "Object", "tags": [], "label": "INTEGRATION_CATEGORY_DISPLAY", - "description": [], + "description": [ + "\nA map of category names and their corresponding titles." + ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, "children": [ @@ -861,9 +893,7 @@ "type": "string", "tags": [], "label": "aws", - "description": [ - "// Known EPR" - ], + "description": [], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false }, @@ -1118,16 +1148,79 @@ "description": [], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.SHIPPER_DISPLAY", + "type": "Object", + "tags": [], + "label": "SHIPPER_DISPLAY", + "description": [ + "\nA map of shipper names and their corresponding titles." + ], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "customIntegrations", + "id": "def-common.SHIPPER_DISPLAY.beats", + "type": "string", + "tags": [], + "label": "beats", + "description": [], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false }, { "parentPluginId": "customIntegrations", - "id": "def-common.INTEGRATION_CATEGORY_DISPLAY.updates_available", + "id": "def-common.SHIPPER_DISPLAY.language_clients", "type": "string", "tags": [], - "label": "updates_available", - "description": [ - "// Internal" - ], + "label": "language_clients", + "description": [], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.SHIPPER_DISPLAY.other", + "type": "string", + "tags": [], + "label": "other", + "description": [], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.SHIPPER_DISPLAY.sample_data", + "type": "string", + "tags": [], + "label": "sample_data", + "description": [], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.SHIPPER_DISPLAY.tests", + "type": "string", + "tags": [], + "label": "tests", + "description": [], + "path": "src/plugins/custom_integrations/common/index.ts", + "deprecated": false + }, + { + "parentPluginId": "customIntegrations", + "id": "def-common.SHIPPER_DISPLAY.tutorial", + "type": "string", + "tags": [], + "label": "tutorial", + "description": [], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false } diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 378d3b16c57fa..a5c470066ad71 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -18,7 +18,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 85 | 1 | 78 | 1 | +| 91 | 1 | 75 | 1 | ## Client diff --git a/api_docs/dashboard.json b/api_docs/dashboard.json index b42846c747bfa..48be2a07d8236 100644 --- a/api_docs/dashboard.json +++ b/api_docs/dashboard.json @@ -1560,7 +1560,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { "pluginId": "data", "scope": "common", @@ -1576,7 +1576,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; removeField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "; removeField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -1608,7 +1608,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "; getField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + "; getField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", { "pluginId": "data", "scope": "common", @@ -1616,7 +1616,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "[K]; getOwnField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "[K]; getOwnField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -2501,7 +2501,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">, \"find\">, embeddableType: string) => Promise<{ [key: string]: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">, \"find\">, embeddableType: string) => Promise<{ [key: string]: ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -2530,7 +2530,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">, \"find\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">, \"find\">" ], "path": "src/plugins/dashboard/server/usage/find_by_value_embeddables.ts", "deprecated": false, diff --git a/api_docs/data.json b/api_docs/data.json index ab02b81539cf2..532c629784c38 100644 --- a/api_docs/data.json +++ b/api_docs/data.json @@ -248,7 +248,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: ", { "pluginId": "data", "scope": "common", @@ -264,7 +264,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", "deprecated": false, @@ -1315,7 +1315,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -1331,7 +1331,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">[]" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">[]" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", "deprecated": false, @@ -1560,7 +1560,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -1576,7 +1576,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">, { addToAggConfigs }?: { addToAggConfigs?: boolean | undefined; }) => T" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">, { addToAggConfigs }?: { addToAggConfigs?: boolean | undefined; }) => T" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", "deprecated": false, @@ -1597,7 +1597,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -1613,7 +1613,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", "deprecated": false, @@ -2504,7 +2504,7 @@ "section": "def-public.PluginInitializerContext", "text": "PluginInitializerContext" }, - "<Readonly<{} & { search: Readonly<{} & { aggs: Readonly<{} & { shardDelay: Readonly<{} & { enabled: boolean; }>; }>; }>; autocomplete: Readonly<{} & { querySuggestions: Readonly<{} & { enabled: boolean; }>; valueSuggestions: Readonly<{} & { enabled: boolean; timeout: moment.Duration; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" + "<Readonly<{} & { search: Readonly<{} & { aggs: Readonly<{} & { shardDelay: Readonly<{} & { enabled: boolean; }>; }>; }>; autocomplete: Readonly<{} & { querySuggestions: Readonly<{} & { enabled: boolean; }>; valueSuggestions: Readonly<{} & { timeout: moment.Duration; enabled: boolean; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" ], "path": "src/plugins/data/public/plugin.ts", "deprecated": false, @@ -3120,18 +3120,6 @@ "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/embeddable/types.ts" @@ -3304,30 +3292,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx" @@ -3456,14 +3420,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/common/types/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/server/routes/existing_fields.test.ts" @@ -3496,14 +3452,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts" @@ -3636,6 +3584,22 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/doc_table/doc_table_wrapper.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts" @@ -3784,6 +3748,18 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/fields/data_view_field.test.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, { "plugin": "dataViews", "path": "src/plugins/data_views/public/index.ts" @@ -3970,11 +3946,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", @@ -3982,7 +3958,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" }, { "plugin": "discover", @@ -4408,250 +4388,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" @@ -4952,22 +4688,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/components/geo_index_pattern_select.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" @@ -4980,14 +4700,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/classes/fields/agg/count_agg_field.d.ts" @@ -5052,14 +4764,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/connected_components/edit_layer_panel/filter_editor/filter_editor.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, { "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/target/types/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.d.ts" @@ -5580,6 +5284,14 @@ "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/target/types/public/components/agg_select.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts" @@ -5628,6 +5340,14 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/utils/nested_fields.d.ts" @@ -7576,7 +7296,7 @@ "\nsets value to a single search source field" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { "pluginId": "data", "scope": "common", @@ -7641,7 +7361,7 @@ "\nremove field" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => this" + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => this" ], "path": "src/plugins/data/common/search/search_source/search_source.ts", "deprecated": false, @@ -7766,7 +7486,7 @@ "\nGets a single field from the fields" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", { "pluginId": "data", "scope": "common", @@ -7820,7 +7540,7 @@ "\nGet the field from our own fields, don't traverse up the chain" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -9284,7 +9004,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".FILTER>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ geo_bounding_box?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", + ".FILTER>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ geo_bounding_box?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", { "pluginId": "data", "scope": "common", @@ -9380,7 +9100,7 @@ "section": "def-common.Query", "text": "Query" }, - "> | undefined; }, never>, \"enabled\" | \"id\" | \"filter\" | \"schema\" | \"geo_bounding_box\" | \"json\" | \"customLabel\" | \"timeShift\">, ", + "> | undefined; }, never>, \"id\" | \"filter\" | \"enabled\" | \"schema\" | \"geo_bounding_box\" | \"json\" | \"customLabel\" | \"timeShift\">, ", "AggExpressionType", ", ", { @@ -9436,7 +9156,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".FILTERS>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"timeShift\"> & Pick<{ filters?: ", + ".FILTERS>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"timeShift\"> & Pick<{ filters?: ", { "pluginId": "expressions", "scope": "common", @@ -9468,7 +9188,7 @@ "section": "def-common.QueryFilter", "text": "QueryFilter" }, - ">[] | undefined; }, never>, \"enabled\" | \"id\" | \"filters\" | \"schema\" | \"json\" | \"timeShift\">, ", + ">[] | undefined; }, never>, \"id\" | \"filters\" | \"enabled\" | \"schema\" | \"json\" | \"timeShift\">, ", "AggExpressionType", ", ", { @@ -9580,7 +9300,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".IP_RANGE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: (", + ".IP_RANGE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: (", { "pluginId": "expressions", "scope": "common", @@ -9644,7 +9364,7 @@ "section": "def-common.IpRange", "text": "IpRange" }, - ">)[] | undefined; ipRangeType?: string | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ipRangeType\" | \"ranges\">, ", + ">)[] | undefined; ipRangeType?: string | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ipRangeType\" | \"ranges\">, ", "AggExpressionType", ", ", { @@ -9700,7 +9420,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".DATE_RANGE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\"> & Pick<{ ranges?: ", + ".DATE_RANGE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\"> & Pick<{ ranges?: ", { "pluginId": "expressions", "scope": "common", @@ -9732,7 +9452,7 @@ "section": "def-common.DateRange", "text": "DateRange" }, - ">[] | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\" | \"time_zone\">, ", + ">[] | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\" | \"time_zone\">, ", "AggExpressionType", ", ", { @@ -9788,7 +9508,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".RANGE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: ", + ".RANGE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: ", { "pluginId": "expressions", "scope": "common", @@ -9820,7 +9540,7 @@ "section": "def-common.NumericalRange", "text": "NumericalRange" }, - ">[] | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\">, ", + ">[] | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\">, ", "AggExpressionType", ", ", { @@ -9932,7 +9652,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".GEOHASH_GRID>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\"> & Pick<{ boundingBox?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", + ".GEOHASH_GRID>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\"> & Pick<{ boundingBox?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", { "pluginId": "data", "scope": "common", @@ -9996,7 +9716,7 @@ "section": "def-common.GeoPoint", "text": "GeoPoint" }, - "; }) | ({ type: \"geo_bounding_box\"; } & WellKnownText) | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\" | \"boundingBox\">, ", + "; }) | ({ type: \"geo_bounding_box\"; } & WellKnownText) | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\" | \"boundingBox\">, ", "AggExpressionType", ", ", { @@ -10052,7 +9772,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".HISTOGRAM>, \"enabled\" | \"interval\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\"> & Pick<{ extended_bounds?: ", + ".HISTOGRAM>, \"interval\" | \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\"> & Pick<{ extended_bounds?: ", { "pluginId": "expressions", "scope": "common", @@ -10084,7 +9804,7 @@ "section": "def-common.ExtendedBounds", "text": "ExtendedBounds" }, - "> | undefined; }, never>, \"enabled\" | \"interval\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\" | \"extended_bounds\">, ", + "> | undefined; }, never>, \"interval\" | \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\" | \"extended_bounds\">, ", "AggExpressionType", ", ", { @@ -10140,7 +9860,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".DATE_HISTOGRAM>, \"enabled\" | \"interval\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\"> & Pick<{ timeRange?: ", + ".DATE_HISTOGRAM>, \"interval\" | \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\"> & Pick<{ timeRange?: ", { "pluginId": "expressions", "scope": "common", @@ -10204,7 +9924,7 @@ "section": "def-common.ExtendedBounds", "text": "ExtendedBounds" }, - "> | undefined; }, never>, \"enabled\" | \"interval\" | \"id\" | \"timeRange\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"extended_bounds\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\">, ", + "> | undefined; }, never>, \"interval\" | \"id\" | \"timeRange\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"extended_bounds\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\">, ", "AggExpressionType", ", ", { @@ -10260,11 +9980,11 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".TERMS>, \"enabled\" | \"id\" | \"size\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\"> & Pick<{ orderAgg?: ", + ".TERMS>, \"id\" | \"size\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\"> & Pick<{ orderAgg?: ", "AggExpressionType", " | undefined; }, \"orderAgg\"> & Pick<{ orderAgg?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"size\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"orderAgg\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\">, ", + " | undefined; }, never>, \"id\" | \"size\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"orderAgg\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\">, ", "AggExpressionType", ", ", { @@ -10376,7 +10096,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".AVG_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".AVG_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -10384,7 +10104,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -10440,7 +10160,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".MAX_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".MAX_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -10448,7 +10168,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -10504,7 +10224,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".MIN_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".MIN_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -10512,7 +10232,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -10568,7 +10288,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".SUM_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".SUM_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -10576,7 +10296,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -10632,7 +10352,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".FILTERED_METRIC>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".FILTERED_METRIC>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -10640,7 +10360,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -10808,11 +10528,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".CUMULATIVE_SUM>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", + ".CUMULATIVE_SUM>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", "AggExpressionType", ", ", { @@ -10868,11 +10588,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".DERIVATIVE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", + ".DERIVATIVE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", "AggExpressionType", ", ", { @@ -11264,11 +10984,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".MOVING_FN>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\"> & Pick<{ customMetric?: ", + ".MOVING_FN>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\">, ", "AggExpressionType", ", ", { @@ -11436,11 +11156,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".SERIAL_DIFF>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", + ".SERIAL_DIFF>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", "AggExpressionType", ", ", { @@ -12387,14 +12107,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx" @@ -12567,34 +12279,6 @@ "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/util_components/single_field_select.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/target/types/public/alerting/common/group_by_expression/group_by_expression.d.ts" @@ -13137,142 +12821,6 @@ "plugin": "timelines", "path": "x-pack/plugins/timelines/public/container/source/index.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/utils/kuery.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/utils/kuery.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_source/with_source.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_source/with_source.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" @@ -13517,30 +13065,6 @@ "plugin": "timelines", "path": "x-pack/plugins/timelines/public/mock/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_kuery_autocompletion.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_kuery_autocompletion.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_source/with_source.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_source/with_source.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/target/types/public/components/kuery_bar/with_kuery_autocompletion.d.ts" @@ -13585,30 +13109,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/target/types/public/network/components/network_top_countries_table/columns.d.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/components/expression_chart.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/components/expression_chart.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/index.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/index.d.ts" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/target/types/public/alerts/components/param_details_form/use_derived_index_pattern.d.ts" @@ -13657,34 +13157,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/target/types/public/ueba/pages/details/types.d.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, { "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx" @@ -13717,70 +13189,6 @@ "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/target/types/public/components/edit_index_pattern/index_header/index_header.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/index.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/index.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts" @@ -13889,14 +13297,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/server/routes/api/transforms.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/mock/index_pattern.ts" @@ -13904,34 +13304,6 @@ { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/mock/index_pattern.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts" } ], "children": [ @@ -14026,9 +13398,9 @@ "signature": [ "Record<string, ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, @@ -15223,7 +14595,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", + "; id?: string | undefined; enabled?: boolean | undefined; schema?: string | undefined; params?: {} | ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -15404,7 +14776,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -15420,7 +14792,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">[] | undefined) => ", + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">[] | undefined) => ", { "pluginId": "data", "scope": "common", @@ -15492,23 +14864,23 @@ "label": "DataViewsContract", "description": [], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -15516,7 +14888,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -15524,7 +14896,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -15674,7 +15046,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false, @@ -17638,6 +17018,10 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/types.ts" @@ -18191,14 +17575,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, { "plugin": "transform", "path": "x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts" @@ -18227,34 +17603,6 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx" @@ -18290,22 +17638,6 @@ { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" } ], "initialIsOpen": false @@ -18429,23 +17761,23 @@ "label": "IndexPatternsContract", "description": [], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -18453,7 +17785,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -18461,7 +17793,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -18611,7 +17943,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": true, @@ -18644,50 +17984,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx" @@ -18776,22 +18072,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/doc/components/doc.tsx" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/context.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/context.ts" - }, { "plugin": "visualizations", "path": "src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts" @@ -18864,66 +18144,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/lazy_load_bundle/index.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/dependency_cache.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/dependency_cache.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/resolvers.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/resolvers.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/router.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/router.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, { "plugin": "graph", "path": "x-pack/plugins/graph/public/application.ts" @@ -18988,30 +18208,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/routing/router.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/routing/router.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/target/types/public/management/roles/edit_role/edit_role_page.d.ts" @@ -19148,14 +18344,6 @@ "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/target/types/public/components/utils.d.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/_stubs.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/_stubs.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/doc/components/doc.d.ts" @@ -19163,14 +18351,6 @@ { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/doc/components/doc.d.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" } ], "initialIsOpen": false @@ -19361,7 +18541,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { "pluginId": "data", "scope": "common", @@ -19377,7 +18557,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; removeField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "; removeField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -19409,7 +18589,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "; getField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + "; getField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", { "pluginId": "data", "scope": "common", @@ -19417,7 +18597,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "[K]; getOwnField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "[K]; getOwnField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -25388,23 +24568,23 @@ "\ndata views service\n{@link DataViewsContract}" ], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25412,7 +24592,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25420,7 +24600,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -25570,7 +24750,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data/public/types.ts", "deprecated": false @@ -25587,23 +24775,23 @@ "\nindex patterns service\n{@link DataViewsContract}" ], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25611,7 +24799,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25619,7 +24807,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -25769,7 +24957,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data/public/types.ts", "deprecated": true, @@ -26672,7 +25868,7 @@ "section": "def-server.PluginInitializerContext", "text": "PluginInitializerContext" }, - "<Readonly<{} & { search: Readonly<{} & { aggs: Readonly<{} & { shardDelay: Readonly<{} & { enabled: boolean; }>; }>; }>; autocomplete: Readonly<{} & { querySuggestions: Readonly<{} & { enabled: boolean; }>; valueSuggestions: Readonly<{} & { enabled: boolean; timeout: moment.Duration; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" + "<Readonly<{} & { search: Readonly<{} & { aggs: Readonly<{} & { shardDelay: Readonly<{} & { enabled: boolean; }>; }>; }>; autocomplete: Readonly<{} & { querySuggestions: Readonly<{} & { enabled: boolean; }>; valueSuggestions: Readonly<{} & { timeout: moment.Duration; enabled: boolean; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" ], "path": "src/plugins/data/server/plugin.ts", "deprecated": false, @@ -28323,13 +27519,21 @@ "signature": [ "(fieldName: string, format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>) => void" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">) => void" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -28357,13 +27561,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -28786,18 +27998,6 @@ "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/embeddable/types.ts" @@ -28970,30 +28170,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx" @@ -29122,14 +28298,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/common/types/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/server/routes/existing_fields.test.ts" @@ -29162,14 +28330,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts" @@ -29302,6 +28462,22 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/doc_table/doc_table_wrapper.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts" @@ -29450,6 +28626,18 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/fields/data_view_field.test.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, { "plugin": "dataViews", "path": "src/plugins/data_views/public/index.ts" @@ -29636,11 +28824,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", @@ -29648,7 +28836,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" }, { "plugin": "discover", @@ -30074,250 +29266,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" @@ -30618,22 +29566,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/components/geo_index_pattern_select.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" @@ -30646,14 +29578,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/classes/fields/agg/count_agg_field.d.ts" @@ -30718,14 +29642,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/connected_components/edit_layer_panel/filter_editor/filter_editor.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, { "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/target/types/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.d.ts" @@ -31246,6 +30162,14 @@ "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/target/types/public/components/agg_select.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts" @@ -31294,6 +30218,14 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/utils/nested_fields.d.ts" @@ -34123,14 +33055,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx" @@ -34303,34 +33227,6 @@ "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/util_components/single_field_select.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/target/types/public/alerting/common/group_by_expression/group_by_expression.d.ts" @@ -36660,6 +35556,10 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/types.ts" @@ -37096,14 +35996,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, { "plugin": "transform", "path": "x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts" @@ -37132,34 +36024,6 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx" @@ -37195,22 +36059,6 @@ { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" } ], "initialIsOpen": false @@ -40706,13 +39554,21 @@ "signature": [ "(fieldName: string, format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>) => void" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">) => void" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -40740,13 +39596,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -41478,14 +40342,38 @@ "parentPluginId": "data", "id": "def-common.DataViewsService.ensureDefaultDataView", "type": "Function", - "tags": [], + "tags": [ + "deprecated" + ], "label": "ensureDefaultDataView", "description": [], "signature": [ "() => Promise<unknown> | undefined" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", - "deprecated": false, + "deprecated": true, + "references": [ + { + "plugin": "dataViews", + "path": "src/plugins/data_views/common/data_views/data_views.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/application/lib/load_saved_dashboard_state.ts" + }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/plugin.ts" + }, + { + "plugin": "visualize", + "path": "src/plugins/visualize/public/plugin.ts" + } + ], "returnComment": [], "children": [] }, @@ -42559,6 +41447,33 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.DataViewsService.getDefaultDataView", + "type": "Function", + "tags": [], + "label": "getDefaultDataView", + "description": [ + "\nReturns the default data view as an object. If no default is found, or it is missing\nanother data view is selected as default and returned." + ], + "signature": [ + "() => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "default data view" + ] } ], "initialIsOpen": false @@ -42997,18 +41912,6 @@ "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/embeddable/types.ts" @@ -43181,30 +42084,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx" @@ -43333,14 +42212,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/common/types/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/server/routes/existing_fields.test.ts" @@ -43373,14 +42244,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts" @@ -43513,6 +42376,22 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/doc_table/doc_table_wrapper.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts" @@ -43661,6 +42540,18 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/fields/data_view_field.test.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, { "plugin": "dataViews", "path": "src/plugins/data_views/public/index.ts" @@ -43847,11 +42738,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", @@ -43859,7 +42750,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" }, { "plugin": "discover", @@ -44285,250 +43180,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" @@ -44829,22 +43480,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/components/geo_index_pattern_select.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" @@ -44857,14 +43492,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/classes/fields/agg/count_agg_field.d.ts" @@ -44929,14 +43556,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/connected_components/edit_layer_panel/filter_editor/filter_editor.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, { "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/target/types/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.d.ts" @@ -45457,6 +44076,14 @@ "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/target/types/public/components/agg_select.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts" @@ -45505,6 +44132,14 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/utils/nested_fields.d.ts" @@ -49402,7 +48037,7 @@ "section": "def-common.IndexPatternLoadExpressionFunctionDefinition", "text": "IndexPatternLoadExpressionFunctionDefinition" }, - ", \"type\" | \"telemetry\" | \"inject\" | \"extract\" | \"migrations\" | \"name\" | \"disabled\" | \"help\" | \"inputTypes\" | \"args\" | \"aliases\" | \"context\">" + ", \"telemetry\" | \"inject\" | \"extract\" | \"migrations\" | \"type\" | \"name\" | \"disabled\" | \"help\" | \"inputTypes\" | \"args\" | \"aliases\" | \"context\">" ], "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", "deprecated": false, @@ -51306,13 +49941,21 @@ "signature": [ "Record<string, ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">> | undefined" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -51505,13 +50148,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -51809,13 +50460,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -52282,14 +50941,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx" @@ -52462,34 +51113,6 @@ "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/util_components/single_field_select.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/target/types/public/alerting/common/group_by_expression/group_by_expression.d.ts" @@ -53032,142 +51655,6 @@ "plugin": "timelines", "path": "x-pack/plugins/timelines/public/container/source/index.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/utils/kuery.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/utils/kuery.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_source/with_source.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_source/with_source.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" @@ -53412,30 +51899,6 @@ "plugin": "timelines", "path": "x-pack/plugins/timelines/public/mock/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_kuery_autocompletion.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_kuery_autocompletion.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_source/with_source.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_source/with_source.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/target/types/public/components/kuery_bar/with_kuery_autocompletion.d.ts" @@ -53480,30 +51943,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/target/types/public/network/components/network_top_countries_table/columns.d.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/components/expression_chart.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/components/expression_chart.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/index.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/index.d.ts" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/target/types/public/alerts/components/param_details_form/use_derived_index_pattern.d.ts" @@ -53552,34 +51991,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/target/types/public/ueba/pages/details/types.d.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, { "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx" @@ -53612,70 +52023,6 @@ "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/target/types/public/components/edit_index_pattern/index_header/index_header.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/index.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/index.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts" @@ -53784,14 +52131,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/server/routes/api/transforms.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/mock/index_pattern.ts" @@ -53799,34 +52138,6 @@ { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/mock/index_pattern.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts" } ], "children": [ @@ -53921,9 +52232,9 @@ "signature": [ "Record<string, ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, @@ -54582,7 +52893,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" + "\"boolean\" | \"keyword\" | \"date\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -55524,23 +53835,23 @@ "label": "DataViewsContract", "description": [], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -55548,7 +53859,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -55556,7 +53867,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -55706,7 +54017,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false, @@ -55820,13 +54139,21 @@ "signature": [ "{ [x: string]: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>; }" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">; }" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, @@ -57434,6 +55761,10 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/types.ts" @@ -58021,14 +56352,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, { "plugin": "transform", "path": "x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts" @@ -58057,34 +56380,6 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx" @@ -58120,22 +56415,6 @@ { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" } ], "initialIsOpen": false @@ -58289,23 +56568,23 @@ "label": "IndexPatternsContract", "description": [], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -58313,7 +56592,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -58321,7 +56600,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -58471,7 +56750,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": true, @@ -58504,50 +56791,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx" @@ -58636,22 +56879,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/doc/components/doc.tsx" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/context.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/context.ts" - }, { "plugin": "visualizations", "path": "src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts" @@ -58724,66 +56951,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/lazy_load_bundle/index.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/dependency_cache.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/dependency_cache.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/resolvers.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/resolvers.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/router.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/router.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, { "plugin": "graph", "path": "x-pack/plugins/graph/public/application.ts" @@ -58848,30 +57015,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/routing/router.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/routing/router.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/target/types/public/management/roles/edit_role/edit_role_page.d.ts" @@ -59008,14 +57151,6 @@ "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/target/types/public/components/utils.d.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/_stubs.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/_stubs.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/doc/components/doc.d.ts" @@ -59023,14 +57158,6 @@ { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/doc/components/doc.d.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" } ], "initialIsOpen": false @@ -59702,7 +57829,7 @@ "label": "RuntimeType", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" + "\"boolean\" | \"keyword\" | \"date\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 0734f19d6c3eb..597810c06e8f4 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3192 | 43 | 2807 | 48 | +| 3193 | 43 | 2807 | 48 | ## Client diff --git a/api_docs/data_autocomplete.mdx b/api_docs/data_autocomplete.mdx index 1eef9ef1c6932..022bb799670da 100644 --- a/api_docs/data_autocomplete.mdx +++ b/api_docs/data_autocomplete.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3192 | 43 | 2807 | 48 | +| 3193 | 43 | 2807 | 48 | ## Client diff --git a/api_docs/data_query.json b/api_docs/data_query.json index e711d7c5bbb76..858e25ebb2b09 100644 --- a/api_docs/data_query.json +++ b/api_docs/data_query.json @@ -1167,7 +1167,7 @@ "section": "def-public.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"bulkUpdate\">) => ", + ", \"create\" | \"bulkCreate\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"bulkUpdate\">) => ", { "pluginId": "data", "scope": "public", @@ -1195,7 +1195,7 @@ "section": "def-public.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"bulkUpdate\">" + ", \"create\" | \"bulkCreate\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"bulkUpdate\">" ], "path": "src/plugins/data/public/query/saved_query/saved_query_service.ts", "deprecated": false, diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index bb88e5868b605..e83e8043e970d 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3192 | 43 | 2807 | 48 | +| 3193 | 43 | 2807 | 48 | ## Client diff --git a/api_docs/data_search.json b/api_docs/data_search.json index 25ed62f473bd3..01cfaaa5d781b 100644 --- a/api_docs/data_search.json +++ b/api_docs/data_search.json @@ -217,11 +217,9 @@ "\nSearch sessions SO CRUD\n{@link ISessionsClient}" ], "signature": [ - "{ get: (sessionId: string) => Promise<", + "{ create: ({ name, appId, urlGeneratorId, initialState, restoreState, sessionId, }: { name: string; appId: string; initialState: Record<string, unknown>; restoreState: Record<string, unknown>; urlGeneratorId: string; sessionId: string; }) => Promise<", "SearchSessionSavedObject", - ">; delete: (sessionId: string) => Promise<void>; create: ({ name, appId, urlGeneratorId, initialState, restoreState, sessionId, }: { name: string; appId: string; initialState: Record<string, unknown>; restoreState: Record<string, unknown>; urlGeneratorId: string; sessionId: string; }) => Promise<", - "SearchSessionSavedObject", - ">; find: (options: Pick<", + ">; delete: (sessionId: string) => Promise<void>; find: (options: Pick<", { "pluginId": "core", "scope": "server", @@ -237,7 +235,9 @@ "section": "def-server.SavedObjectsFindResponse", "text": "SavedObjectsFindResponse" }, - "<unknown, unknown>>; update: (sessionId: string, attributes: unknown) => Promise<", + "<unknown, unknown>>; get: (sessionId: string) => Promise<", + "SearchSessionSavedObject", + ">; update: (sessionId: string, attributes: unknown) => Promise<", { "pluginId": "core", "scope": "server", @@ -379,7 +379,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -395,7 +395,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">[] | undefined) => ", + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">[] | undefined) => ", { "pluginId": "data", "scope": "common", @@ -617,11 +617,9 @@ "\nSearch sessions SO CRUD\n{@link ISessionsClient}" ], "signature": [ - "{ get: (sessionId: string) => Promise<", + "{ create: ({ name, appId, urlGeneratorId, initialState, restoreState, sessionId, }: { name: string; appId: string; initialState: Record<string, unknown>; restoreState: Record<string, unknown>; urlGeneratorId: string; sessionId: string; }) => Promise<", "SearchSessionSavedObject", - ">; delete: (sessionId: string) => Promise<void>; create: ({ name, appId, urlGeneratorId, initialState, restoreState, sessionId, }: { name: string; appId: string; initialState: Record<string, unknown>; restoreState: Record<string, unknown>; urlGeneratorId: string; sessionId: string; }) => Promise<", - "SearchSessionSavedObject", - ">; find: (options: Pick<", + ">; delete: (sessionId: string) => Promise<void>; find: (options: Pick<", { "pluginId": "core", "scope": "server", @@ -637,7 +635,9 @@ "section": "def-server.SavedObjectsFindResponse", "text": "SavedObjectsFindResponse" }, - "<unknown, unknown>>; update: (sessionId: string, attributes: unknown) => Promise<", + "<unknown, unknown>>; get: (sessionId: string) => Promise<", + "SearchSessionSavedObject", + ">; update: (sessionId: string, attributes: unknown) => Promise<", { "pluginId": "core", "scope": "server", @@ -957,11 +957,9 @@ "label": "ISessionsClient", "description": [], "signature": [ - "{ get: (sessionId: string) => Promise<", + "{ create: ({ name, appId, urlGeneratorId, initialState, restoreState, sessionId, }: { name: string; appId: string; initialState: Record<string, unknown>; restoreState: Record<string, unknown>; urlGeneratorId: string; sessionId: string; }) => Promise<", "SearchSessionSavedObject", - ">; delete: (sessionId: string) => Promise<void>; create: ({ name, appId, urlGeneratorId, initialState, restoreState, sessionId, }: { name: string; appId: string; initialState: Record<string, unknown>; restoreState: Record<string, unknown>; urlGeneratorId: string; sessionId: string; }) => Promise<", - "SearchSessionSavedObject", - ">; find: (options: Pick<", + ">; delete: (sessionId: string) => Promise<void>; find: (options: Pick<", { "pluginId": "core", "scope": "server", @@ -977,7 +975,9 @@ "section": "def-server.SavedObjectsFindResponse", "text": "SavedObjectsFindResponse" }, - "<unknown, unknown>>; update: (sessionId: string, attributes: unknown) => Promise<", + "<unknown, unknown>>; get: (sessionId: string) => Promise<", + "SearchSessionSavedObject", + ">; update: (sessionId: string, attributes: unknown) => Promise<", { "pluginId": "core", "scope": "server", @@ -1921,25 +1921,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -1997,7 +1979,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -2061,6 +2051,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -2593,7 +2593,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: ", { "pluginId": "data", "scope": "common", @@ -2609,7 +2609,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", "deprecated": false, @@ -3660,7 +3660,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -3676,7 +3676,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">[]" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">[]" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", "deprecated": false, @@ -3905,7 +3905,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -3921,7 +3921,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">, { addToAggConfigs }?: { addToAggConfigs?: boolean | undefined; }) => T" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">, { addToAggConfigs }?: { addToAggConfigs?: boolean | undefined; }) => T" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", "deprecated": false, @@ -3942,7 +3942,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -3958,7 +3958,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">" + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", "deprecated": false, @@ -4967,7 +4967,7 @@ "\nThe type the values produced by this agg will have in the final data table.\nIf not specified, the type of the field is used." ], "signature": [ - "\"string\" | \"number\" | \"boolean\" | \"object\" | \"date\" | \"_source\" | \"attachment\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\" | undefined" + "\"string\" | \"number\" | \"boolean\" | \"object\" | \"_source\" | \"attachment\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\" | undefined" ], "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false @@ -5289,7 +5289,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { "pluginId": "data", "scope": "common", @@ -5305,7 +5305,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; removeField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "; removeField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -5337,7 +5337,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "; getField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + "; getField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", { "pluginId": "data", "scope": "common", @@ -5345,7 +5345,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "[K]; getOwnField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "[K]; getOwnField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -5528,13 +5528,21 @@ "signature": [ "(agg: TAggConfig) => ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">" ], "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, @@ -7556,7 +7564,7 @@ "\nsets value to a single search source field" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { "pluginId": "data", "scope": "common", @@ -7621,7 +7629,7 @@ "\nremove field" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => this" + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => this" ], "path": "src/plugins/data/common/search/search_source/search_source.ts", "deprecated": false, @@ -7746,7 +7754,7 @@ "\nGets a single field from the fields" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", { "pluginId": "data", "scope": "common", @@ -7800,7 +7808,7 @@ "\nGet the field from our own fields, don't traverse up the chain" ], "signature": [ - "<K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "<K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -8381,7 +8389,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">, dependencies: ", + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">, dependencies: ", { "pluginId": "data", "scope": "common", @@ -8434,7 +8442,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">" + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">" ], "path": "src/plugins/data/common/search/search_source/search_source_service.ts", "deprecated": false, @@ -9388,7 +9396,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">, searchSourceDependencies: ", + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">, searchSourceDependencies: ", { "pluginId": "data", "scope": "common", @@ -9435,7 +9443,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">" + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">" ], "path": "src/plugins/data/common/search/search_source/create_search_source.ts", "deprecated": false, @@ -13382,7 +13390,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".FILTER>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ geo_bounding_box?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", + ".FILTER>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ geo_bounding_box?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", { "pluginId": "data", "scope": "common", @@ -13478,7 +13486,7 @@ "section": "def-common.Query", "text": "Query" }, - "> | undefined; }, never>, \"enabled\" | \"id\" | \"filter\" | \"schema\" | \"geo_bounding_box\" | \"json\" | \"customLabel\" | \"timeShift\">, ", + "> | undefined; }, never>, \"id\" | \"filter\" | \"enabled\" | \"schema\" | \"geo_bounding_box\" | \"json\" | \"customLabel\" | \"timeShift\">, ", "AggExpressionType", ", ", { @@ -13534,7 +13542,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".FILTERS>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"timeShift\"> & Pick<{ filters?: ", + ".FILTERS>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"timeShift\"> & Pick<{ filters?: ", { "pluginId": "expressions", "scope": "common", @@ -13566,7 +13574,7 @@ "section": "def-common.QueryFilter", "text": "QueryFilter" }, - ">[] | undefined; }, never>, \"enabled\" | \"id\" | \"filters\" | \"schema\" | \"json\" | \"timeShift\">, ", + ">[] | undefined; }, never>, \"id\" | \"filters\" | \"enabled\" | \"schema\" | \"json\" | \"timeShift\">, ", "AggExpressionType", ", ", { @@ -13678,7 +13686,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".IP_RANGE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: (", + ".IP_RANGE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: (", { "pluginId": "expressions", "scope": "common", @@ -13742,7 +13750,7 @@ "section": "def-common.IpRange", "text": "IpRange" }, - ">)[] | undefined; ipRangeType?: string | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ipRangeType\" | \"ranges\">, ", + ">)[] | undefined; ipRangeType?: string | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ipRangeType\" | \"ranges\">, ", "AggExpressionType", ", ", { @@ -13798,7 +13806,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".DATE_RANGE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\"> & Pick<{ ranges?: ", + ".DATE_RANGE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\"> & Pick<{ ranges?: ", { "pluginId": "expressions", "scope": "common", @@ -13830,7 +13838,7 @@ "section": "def-common.DateRange", "text": "DateRange" }, - ">[] | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\" | \"time_zone\">, ", + ">[] | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\" | \"time_zone\">, ", "AggExpressionType", ", ", { @@ -13886,7 +13894,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".RANGE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: ", + ".RANGE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\"> & Pick<{ ranges?: ", { "pluginId": "expressions", "scope": "common", @@ -13918,7 +13926,7 @@ "section": "def-common.NumericalRange", "text": "NumericalRange" }, - ">[] | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\">, ", + ">[] | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"ranges\">, ", "AggExpressionType", ", ", { @@ -14030,7 +14038,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".GEOHASH_GRID>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\"> & Pick<{ boundingBox?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", + ".GEOHASH_GRID>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\"> & Pick<{ boundingBox?: ({ type: \"geo_bounding_box\"; } & GeoBox) | ({ type: \"geo_bounding_box\"; } & { top_left: ", { "pluginId": "data", "scope": "common", @@ -14094,7 +14102,7 @@ "section": "def-common.GeoPoint", "text": "GeoPoint" }, - "; }) | ({ type: \"geo_bounding_box\"; } & WellKnownText) | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\" | \"boundingBox\">, ", + "; }) | ({ type: \"geo_bounding_box\"; } & WellKnownText) | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"autoPrecision\" | \"precision\" | \"useGeocentroid\" | \"isFilteredByCollar\" | \"boundingBox\">, ", "AggExpressionType", ", ", { @@ -14150,7 +14158,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".HISTOGRAM>, \"enabled\" | \"interval\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\"> & Pick<{ extended_bounds?: ", + ".HISTOGRAM>, \"interval\" | \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\"> & Pick<{ extended_bounds?: ", { "pluginId": "expressions", "scope": "common", @@ -14182,7 +14190,7 @@ "section": "def-common.ExtendedBounds", "text": "ExtendedBounds" }, - "> | undefined; }, never>, \"enabled\" | \"interval\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\" | \"extended_bounds\">, ", + "> | undefined; }, never>, \"interval\" | \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"used_interval\" | \"maxBars\" | \"intervalBase\" | \"min_doc_count\" | \"has_extended_bounds\" | \"extended_bounds\">, ", "AggExpressionType", ", ", { @@ -14238,7 +14246,7 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".DATE_HISTOGRAM>, \"enabled\" | \"interval\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\"> & Pick<{ timeRange?: ", + ".DATE_HISTOGRAM>, \"interval\" | \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\"> & Pick<{ timeRange?: ", { "pluginId": "expressions", "scope": "common", @@ -14302,7 +14310,7 @@ "section": "def-common.ExtendedBounds", "text": "ExtendedBounds" }, - "> | undefined; }, never>, \"enabled\" | \"interval\" | \"id\" | \"timeRange\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"extended_bounds\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\">, ", + "> | undefined; }, never>, \"interval\" | \"id\" | \"timeRange\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"time_zone\" | \"used_interval\" | \"min_doc_count\" | \"extended_bounds\" | \"useNormalizedEsInterval\" | \"scaleMetricValues\" | \"used_time_zone\" | \"drop_partials\" | \"format\">, ", "AggExpressionType", ", ", { @@ -14358,11 +14366,11 @@ "section": "def-common.BUCKET_TYPES", "text": "BUCKET_TYPES" }, - ".TERMS>, \"enabled\" | \"id\" | \"size\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\"> & Pick<{ orderAgg?: ", + ".TERMS>, \"id\" | \"size\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\"> & Pick<{ orderAgg?: ", "AggExpressionType", " | undefined; }, \"orderAgg\"> & Pick<{ orderAgg?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"size\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"orderAgg\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\">, ", + " | undefined; }, never>, \"id\" | \"size\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"field\" | \"orderBy\" | \"orderAgg\" | \"order\" | \"missingBucket\" | \"missingBucketLabel\" | \"otherBucket\" | \"otherBucketLabel\" | \"exclude\" | \"include\">, ", "AggExpressionType", ", ", { @@ -14474,7 +14482,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".AVG_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".AVG_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -14482,7 +14490,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -14538,7 +14546,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".MAX_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".MAX_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -14546,7 +14554,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -14602,7 +14610,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".MIN_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".MIN_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -14610,7 +14618,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -14666,7 +14674,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".SUM_BUCKET>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".SUM_BUCKET>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -14674,7 +14682,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -14730,7 +14738,7 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".FILTERED_METRIC>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", + ".FILTERED_METRIC>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\"> & Pick<{ customBucket?: ", "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", @@ -14738,7 +14746,7 @@ "AggExpressionType", " | undefined; customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"customBucket\">, ", "AggExpressionType", ", ", { @@ -14906,11 +14914,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".CUMULATIVE_SUM>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", + ".CUMULATIVE_SUM>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", "AggExpressionType", ", ", { @@ -14966,11 +14974,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".DERIVATIVE>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", + ".DERIVATIVE>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", "AggExpressionType", ", ", { @@ -15362,11 +15370,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".MOVING_FN>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\"> & Pick<{ customMetric?: ", + ".MOVING_FN>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\" | \"window\" | \"script\">, ", "AggExpressionType", ", ", { @@ -15534,11 +15542,11 @@ "section": "def-common.METRIC_TYPES", "text": "METRIC_TYPES" }, - ".SERIAL_DIFF>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", + ".SERIAL_DIFF>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"buckets_path\" | \"metricAgg\"> & Pick<{ customMetric?: ", "AggExpressionType", " | undefined; }, \"customMetric\"> & Pick<{ customMetric?: ", "AggExpressionType", - " | undefined; }, never>, \"enabled\" | \"id\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", + " | undefined; }, never>, \"id\" | \"enabled\" | \"schema\" | \"json\" | \"customLabel\" | \"timeShift\" | \"customMetric\" | \"buckets_path\" | \"metricAgg\">, ", "AggExpressionType", ", ", { @@ -18302,7 +18310,7 @@ "label": "valueType", "description": [], "signature": [ - "\"string\" | \"number\" | \"boolean\" | \"object\" | \"date\" | \"_source\" | \"attachment\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\" | undefined" + "\"string\" | \"number\" | \"boolean\" | \"object\" | \"_source\" | \"attachment\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\" | undefined" ], "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false @@ -18397,13 +18405,21 @@ "signature": [ "((agg: TAggConfig) => ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>) | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">) | undefined" ], "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, @@ -22456,7 +22472,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", + "; id?: string | undefined; enabled?: boolean | undefined; schema?: string | undefined; params?: {} | ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -22945,7 +22961,7 @@ "section": "def-server.SerializableRecord", "text": "SerializableRecord" }, - " | undefined; schema?: string | undefined; }, \"enabled\" | \"id\" | \"schema\" | \"params\"> & Pick<{ type: string | ", + " | undefined; schema?: string | undefined; }, \"id\" | \"enabled\" | \"schema\" | \"params\"> & Pick<{ type: string | ", { "pluginId": "data", "scope": "common", @@ -22961,7 +22977,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; }, never>, \"type\" | \"enabled\" | \"id\" | \"schema\" | \"params\">[] | undefined) => ", + "; }, never>, \"type\" | \"id\" | \"enabled\" | \"schema\" | \"params\">[] | undefined) => ", { "pluginId": "data", "scope": "common", @@ -23132,7 +23148,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", + "; id?: string | undefined; enabled?: boolean | undefined; schema?: string | undefined; params?: {} | ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -25452,7 +25468,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { "pluginId": "data", "scope": "common", @@ -25468,7 +25484,7 @@ "section": "def-common.SearchSource", "text": "SearchSource" }, - "; removeField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "; removeField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", @@ -25500,7 +25516,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "; getField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + "; getField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", { "pluginId": "data", "scope": "common", @@ -25508,7 +25524,7 @@ "section": "def-common.SearchSourceFields", "text": "SearchSourceFields" }, - "[K]; getOwnField: <K extends \"type\" | \"from\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + "[K]; getOwnField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", { "pluginId": "data", "scope": "common", diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index c7256296f1634..d4d521164f6ce 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3192 | 43 | 2807 | 48 | +| 3193 | 43 | 2807 | 48 | ## Client diff --git a/api_docs/data_ui.mdx b/api_docs/data_ui.mdx index 39a1948d15c2c..81fec9e59c0da 100644 --- a/api_docs/data_ui.mdx +++ b/api_docs/data_ui.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3192 | 43 | 2807 | 48 | +| 3193 | 43 | 2807 | 48 | ## Client diff --git a/api_docs/data_views.json b/api_docs/data_views.json index c77aa02425e22..1d6f430c302c2 100644 --- a/api_docs/data_views.json +++ b/api_docs/data_views.json @@ -1357,13 +1357,21 @@ "signature": [ "(fieldName: string, format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>) => void" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">) => void" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -1391,13 +1399,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -1647,7 +1663,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">, ", + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">, ", "DataViewsPublicSetupDependencies", ", ", "DataViewsPublicStartDependencies", @@ -1682,7 +1698,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">>, { expressions }: ", + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">>, { expressions }: ", "DataViewsPublicSetupDependencies", ") => ", { @@ -1721,7 +1737,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">>" + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">>" ], "path": "src/plugins/data_views/public/plugin.ts", "deprecated": false, @@ -1770,7 +1786,7 @@ "section": "def-common.DataViewsService", "text": "DataViewsService" }, - ", \"get\" | \"delete\" | \"create\" | \"find\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\">" + ", \"create\" | \"delete\" | \"find\" | \"get\" | \"ensureDefaultDataView\" | \"getIds\" | \"getTitles\" | \"getIdsWithTitle\" | \"clearCache\" | \"getCache\" | \"getDefault\" | \"getDefaultId\" | \"setDefault\" | \"hasUserDataView\" | \"getFieldsForWildcard\" | \"getFieldsForIndexPattern\" | \"refreshFields\" | \"fieldArrayToMap\" | \"savedObjectToSpec\" | \"createAndSave\" | \"createSavedObject\" | \"updateSavedObject\" | \"getDefaultDataView\">" ], "path": "src/plugins/data_views/public/plugin.ts", "deprecated": false, @@ -1844,14 +1860,34 @@ "parentPluginId": "dataViews", "id": "def-public.DataViewsService.ensureDefaultDataView", "type": "Function", - "tags": [], + "tags": [ + "deprecated" + ], "label": "ensureDefaultDataView", "description": [], "signature": [ "() => Promise<unknown> | undefined" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", - "deprecated": false, + "deprecated": true, + "references": [ + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/application/lib/load_saved_dashboard_state.ts" + }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/plugin.ts" + }, + { + "plugin": "visualize", + "path": "src/plugins/visualize/public/plugin.ts" + } + ], "returnComment": [], "children": [] }, @@ -2925,6 +2961,33 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "dataViews", + "id": "def-public.DataViewsService.getDefaultDataView", + "type": "Function", + "tags": [], + "label": "getDefaultDataView", + "description": [ + "\nReturns the default data view as an object. If no default is found, or it is missing\nanother data view is selected as default and returned." + ], + "signature": [ + "() => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "default data view" + ] } ], "initialIsOpen": false @@ -3446,18 +3509,6 @@ "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/embeddable/types.ts" @@ -3630,30 +3681,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx" @@ -3782,14 +3809,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/common/types/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/server/routes/existing_fields.test.ts" @@ -3822,14 +3841,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts" @@ -4190,6 +4201,22 @@ "plugin": "data", "path": "src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts" @@ -4330,6 +4357,18 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/doc_table/components/table_header/table_header.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, { "plugin": "data", "path": "src/plugins/data/public/index.ts" @@ -4536,11 +4575,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", @@ -4548,7 +4587,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" }, { "plugin": "discover", @@ -4974,250 +5017,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" @@ -5518,22 +5317,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/components/geo_index_pattern_select.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" @@ -5547,16 +5330,8 @@ "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, - { - "plugin": "maps", - "path": "x-pack/plugins/maps/target/types/public/classes/fields/agg/count_agg_field.d.ts" + "plugin": "maps", + "path": "x-pack/plugins/maps/target/types/public/classes/fields/agg/count_agg_field.d.ts" }, { "plugin": "maps", @@ -5618,14 +5393,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/connected_components/edit_layer_panel/filter_editor/filter_editor.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, { "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/target/types/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.d.ts" @@ -6146,6 +5913,14 @@ "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/target/types/public/components/agg_select.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts" @@ -6194,6 +5969,14 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/utils/nested_fields.d.ts" @@ -8020,7 +7803,7 @@ "section": "def-public.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"delete\" | \"create\" | \"find\" | \"resolve\" | \"update\">" + ", \"create\" | \"delete\" | \"find\" | \"resolve\" | \"update\">" ], "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", "deprecated": false, @@ -8405,7 +8188,7 @@ "signature": [ "<T = any>() => Promise<Record<string, Pick<", "UiSettingsParams", - "<unknown>, \"type\" | \"options\" | \"description\" | \"name\" | \"order\" | \"value\" | \"category\" | \"optionLabels\" | \"requiresPageReload\" | \"readonly\" | \"sensitive\" | \"deprecation\" | \"metric\"> & ", + "<unknown>, \"type\" | \"description\" | \"name\" | \"options\" | \"order\" | \"value\" | \"category\" | \"optionLabels\" | \"requiresPageReload\" | \"readonly\" | \"sensitive\" | \"deprecation\" | \"metric\"> & ", "UserProvidedValues", "<T>>>" ], @@ -9219,23 +9002,23 @@ "\nData plugin public Start contract" ], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -9243,7 +9026,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -9251,7 +9034,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -9401,7 +9184,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/public/types.ts", "deprecated": false, @@ -9618,7 +9409,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", { "pluginId": "core", "scope": "server", @@ -9642,7 +9433,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", { "pluginId": "core", "scope": "server", @@ -10052,7 +9843,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", { "pluginId": "core", "scope": "server", @@ -10162,7 +9953,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, index: string) => Promise<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, index: string) => Promise<", "SavedObject", "<", { @@ -10193,7 +9984,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "src/plugins/data_views/server/utils.ts", "deprecated": false, @@ -10608,7 +10399,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", { "pluginId": "core", "scope": "server", @@ -10638,25 +10429,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -10714,7 +10487,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -10778,6 +10559,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -10977,7 +10768,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -11010,7 +10801,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, elasticsearchClient: ", { "pluginId": "core", "scope": "server", @@ -11094,25 +10885,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -11170,7 +10943,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -11234,6 +11015,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -11433,7 +11224,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -12823,13 +12614,21 @@ "signature": [ "(fieldName: string, format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>) => void" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">) => void" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -12857,13 +12656,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">" ], "path": "src/plugins/data_views/common/data_views/data_view.ts", "deprecated": false, @@ -13595,14 +13402,34 @@ "parentPluginId": "dataViews", "id": "def-common.DataViewsService.ensureDefaultDataView", "type": "Function", - "tags": [], + "tags": [ + "deprecated" + ], "label": "ensureDefaultDataView", "description": [], "signature": [ "() => Promise<unknown> | undefined" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", - "deprecated": false, + "deprecated": true, + "references": [ + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/application/lib/load_saved_dashboard_state.ts" + }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/plugin.ts" + }, + { + "plugin": "visualize", + "path": "src/plugins/visualize/public/plugin.ts" + } + ], "returnComment": [], "children": [] }, @@ -14676,6 +14503,33 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewsService.getDefaultDataView", + "type": "Function", + "tags": [], + "label": "getDefaultDataView", + "description": [ + "\nReturns the default data view as an object. If no default is found, or it is missing\nanother data view is selected as default and returned." + ], + "signature": [ + "() => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "default data view" + ] } ], "initialIsOpen": false @@ -15250,18 +15104,6 @@ "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/embeddable/types.ts" @@ -15434,30 +15276,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/types.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx" @@ -15586,14 +15404,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/common/types/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/server/routes/existing_fields.test.ts" @@ -15626,14 +15436,6 @@ "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts" @@ -15994,6 +15796,22 @@ "plugin": "data", "path": "src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.successors.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts" @@ -16134,6 +15952,18 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/components/doc_table/components/table_header/table_header.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts" + }, { "plugin": "data", "path": "src/plugins/data/public/index.ts" @@ -16340,11 +16170,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts" + "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" }, { "plugin": "discover", @@ -16352,7 +16182,11 @@ }, { "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/context.ts" }, { "plugin": "discover", @@ -16779,316 +16613,72 @@ "path": "x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/types/app_state.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/field_format_service.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/types/app_state.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/state_management/datasource.sagas.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/state_management/datasource.sagas.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/search_bar.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/search_bar.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/search_bar.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/search_bar.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/inspect_panel.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts" - }, - { - "plugin": "apm", - "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" - }, - { - "plugin": "apm", - "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" - }, - { - "plugin": "apm", - "path": "x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/types/app_state.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/types/app_state.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/services/persistence/deserialize.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/state_management/datasource.sagas.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/state_management/datasource.sagas.ts" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/components/search_bar.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/components/search_bar.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/components/search_bar.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/components/search_bar.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/components/inspect_panel.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/components/inspect_panel.tsx" + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/inspect_panel.tsx" }, { "plugin": "graph", @@ -17322,22 +16912,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/components/geo_index_pattern_select.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" @@ -17350,14 +16924,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/classes/fields/agg/count_agg_field.d.ts" @@ -17422,14 +16988,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/connected_components/edit_layer_panel/filter_editor/filter_editor.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/components/full_time_range_selector/full_time_range_selector.d.ts" - }, { "plugin": "dataVisualizer", "path": "x-pack/plugins/data_visualizer/target/types/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.d.ts" @@ -17950,6 +17508,14 @@ "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/target/types/public/components/agg_select.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/public/application/apps/context/services/anchor.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts" @@ -17998,6 +17564,14 @@ "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, + { + "plugin": "discover", + "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/main/utils/nested_fields.d.ts" @@ -19953,7 +19527,7 @@ "section": "def-common.IndexPatternLoadExpressionFunctionDefinition", "text": "IndexPatternLoadExpressionFunctionDefinition" }, - ", \"type\" | \"telemetry\" | \"inject\" | \"extract\" | \"migrations\" | \"name\" | \"disabled\" | \"help\" | \"inputTypes\" | \"args\" | \"aliases\" | \"context\">" + ", \"telemetry\" | \"inject\" | \"extract\" | \"migrations\" | \"type\" | \"name\" | \"disabled\" | \"help\" | \"inputTypes\" | \"args\" | \"aliases\" | \"context\">" ], "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", "deprecated": false, @@ -20480,13 +20054,21 @@ "signature": [ "Record<string, ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">> | undefined" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -20679,13 +20261,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -20983,13 +20573,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -21444,14 +21042,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_grid/common.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx" @@ -21624,34 +21214,6 @@ "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/util_components/single_field_select.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/field_types_utils.test.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/target/types/public/alerting/common/group_by_expression/group_by_expression.d.ts" @@ -22447,172 +22009,36 @@ "path": "x-pack/plugins/timelines/public/container/source/index.tsx" }, { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" }, { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" }, { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" }, { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" }, { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/utils/kuery.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/utils/kuery.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_source/with_source.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/with_source/with_source.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" + "plugin": "monitoring", + "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" }, { "plugin": "securitySolution", @@ -22826,30 +22252,6 @@ "plugin": "timelines", "path": "x-pack/plugins/timelines/public/mock/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_kuery_autocompletion.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_kuery_autocompletion.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_source/with_source.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/containers/with_source/with_source.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/target/types/public/components/kuery_bar/with_kuery_autocompletion.d.ts" @@ -22894,30 +22296,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/target/types/public/network/components/network_top_countries_table/columns.d.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/components/expression_chart.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/components/expression_chart.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/alerting/metric_threshold/hooks/use_metrics_explorer_chart_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/index.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/index.d.ts" - }, { "plugin": "monitoring", "path": "x-pack/plugins/monitoring/target/types/public/alerts/components/param_details_form/use_derived_index_pattern.d.ts" @@ -22966,34 +22344,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/target/types/public/ueba/pages/details/types.d.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/jobs/new_job/common/index_pattern_context.d.ts" - }, { "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx" @@ -23026,70 +22376,6 @@ "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/target/types/public/components/edit_index_pattern/index_header/index_header.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/index.tsx" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/pages/metrics/index.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts" @@ -23198,14 +22484,6 @@ "plugin": "transform", "path": "x-pack/plugins/transform/server/routes/api/transforms.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/mock/index_pattern.ts" @@ -23214,34 +22492,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/mock/index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts" - }, { "plugin": "data", "path": "src/plugins/data/common/query/timefilter/get_time.test.ts" @@ -23399,9 +22649,9 @@ "signature": [ "Record<string, ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, @@ -23997,7 +23247,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" + "\"boolean\" | \"keyword\" | \"date\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false @@ -24846,23 +24096,23 @@ "label": "DataViewsContract", "description": [], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -24870,7 +24120,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -24878,7 +24128,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -25028,7 +24278,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false, @@ -25044,13 +24302,21 @@ "signature": [ "{ [x: string]: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>; }" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">; }" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, @@ -25213,14 +24479,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, { "plugin": "transform", "path": "x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts" @@ -25253,34 +24511,6 @@ "plugin": "data", "path": "src/plugins/data/server/index.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx" @@ -25316,22 +24546,6 @@ { "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/common/types/kibana.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/common/types/kibana.d.ts" } ], "initialIsOpen": false @@ -25485,23 +24699,23 @@ "label": "IndexPatternsContract", "description": [], "signature": [ - "{ get: (id: string) => Promise<", + "{ create: (spec: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" }, - ">; delete: (indexPatternId: string) => Promise<{}>; create: (spec: ", + ", skipFetchFields?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" + "section": "def-common.DataView", + "text": "DataView" }, - ", skipFetchFields?: boolean) => Promise<", + ">; delete: (indexPatternId: string) => Promise<{}>; find: (search: string, size?: number) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25509,7 +24723,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ">; find: (search: string, size?: number) => Promise<", + "[]>; get: (id: string) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25517,7 +24731,7 @@ "section": "def-common.DataView", "text": "DataView" }, - "[]>; ensureDefaultDataView: ", + ">; ensureDefaultDataView: ", "EnsureDefaultDataView", "; getIds: (refresh?: boolean) => Promise<string[]>; getTitles: (refresh?: boolean) => Promise<string[]>; getIdsWithTitle: (refresh?: boolean) => Promise<", { @@ -25667,7 +24881,15 @@ "section": "def-common.DataView", "text": "DataView" }, - ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; }" + ", saveAttempts?: number, ignoreErrors?: boolean) => Promise<void | Error>; getDefaultDataView: () => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | undefined>; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": true, @@ -25732,50 +24954,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts" }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, - { - "plugin": "infra", - "path": "x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts" - }, { "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx" @@ -25948,22 +25126,6 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/apps/doc/components/doc.tsx" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/anchor.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/context.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/context.ts" - }, { "plugin": "visualizations", "path": "src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts" @@ -26036,66 +25198,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/public/lazy_load_bundle/index.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/dependency_cache.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/dependency_cache.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/resolvers.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/resolvers.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/router.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/routing/router.tsx" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts" - }, { "plugin": "graph", "path": "x-pack/plugins/graph/public/application.ts" @@ -26160,30 +25262,6 @@ "plugin": "maps", "path": "x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts" }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/routing/router.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/routing/router.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts" - }, - { - "plugin": "ml", - "path": "x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/target/types/public/management/roles/edit_role/edit_role_page.d.ts" @@ -26352,14 +25430,6 @@ "plugin": "indexPatternManagement", "path": "src/plugins/index_pattern_management/target/types/public/components/utils.d.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/_stubs.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/context/services/_stubs.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/doc/components/doc.d.ts" @@ -26367,14 +25437,6 @@ { "plugin": "discover", "path": "src/plugins/discover/target/types/public/application/apps/doc/components/doc.d.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/target/types/public/application/apps/context/services/context.d.ts" } ], "initialIsOpen": false @@ -26586,7 +25648,7 @@ "label": "RuntimeType", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" + "\"boolean\" | \"keyword\" | \"date\" | \"geo_point\" | \"ip\" | \"long\" | \"double\"" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index e907c075b9a8f..77f14d3d39a25 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 681 | 6 | 541 | 5 | +| 683 | 6 | 541 | 5 | ## Client diff --git a/api_docs/data_visualizer.json b/api_docs/data_visualizer.json index 6e46a32aabda7..4a0e41ac2318c 100644 --- a/api_docs/data_visualizer.json +++ b/api_docs/data_visualizer.json @@ -574,7 +574,7 @@ "label": "type", "description": [], "signature": [ - "\"number\" | \"boolean\" | \"date\" | \"keyword\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"unknown\" | \"histogram\" | \"text\"" + "\"number\" | \"boolean\" | \"keyword\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"unknown\" | \"histogram\" | \"text\"" ], "path": "x-pack/plugins/data_visualizer/common/types/field_request_config.ts", "deprecated": false @@ -1004,7 +1004,7 @@ "label": "JobFieldType", "description": [], "signature": [ - "\"number\" | \"boolean\" | \"date\" | \"keyword\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"unknown\" | \"histogram\" | \"text\"" + "\"number\" | \"boolean\" | \"keyword\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"unknown\" | \"histogram\" | \"text\"" ], "path": "x-pack/plugins/data_visualizer/common/types/job_field_type.ts", "deprecated": false, diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index a083c82e69d05..341a6b6b6bb33 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -14,27 +14,27 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Referencing plugin(s) | Remove By | | ---------------|-----------|-----------| | <DocLink id="kibDashboardPluginApi" section="def-public.DashboardStart.dashboardUrlGenerator" text="dashboardUrlGenerator"/> | securitySolution | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | dataViews, visTypeTimeseries, reporting, discover, observability, infra, maps, dataVisualizer, ml, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega, data | - | +| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | dataViews, visTypeTimeseries, reporting, discover, observability, maps, dataVisualizer, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega, data | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | dataViews, discover, maps, dataVisualizer, lens, indexPatternFieldEditor, securitySolution, indexPatternEditor, indexPatternManagement, inputControlVis, visDefaultEditor, visTypeTimeseries, data | - | -| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | dataViews, timelines, infra, ml, monitoring, securitySolution, indexPatternManagement, stackAlerts, transform | - | +| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | dataViews, timelines, monitoring, securitySolution, indexPatternManagement, stackAlerts, transform | - | | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | home, savedObjects, security, fleet, indexPatternFieldEditor, discover, visualizations, dashboard, lens, observability, maps, fileUpload, dataVisualizer, ml, infra, apm, graph, monitoring, osquery, securitySolution, stackAlerts, transform, upgradeAssistant, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, kibanaOverview, savedObjectsManagement, visualize, visTypeTimelion, visTypeTimeseries, visTypeVega | - | -| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | dataViews, timelines, infra, ml, monitoring, securitySolution, indexPatternManagement, stackAlerts, transform, data | - | +| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | dataViews, timelines, monitoring, securitySolution, indexPatternManagement, stackAlerts, transform, data | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | dataViews, discover, maps, dataVisualizer, lens, indexPatternFieldEditor, securitySolution, indexPatternEditor, indexPatternManagement, inputControlVis, visDefaultEditor, visTypeTimeseries, data | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | dataViews, visTypeTimeseries, reporting, discover, observability, infra, maps, dataVisualizer, ml, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega, data | - | +| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | dataViews, visTypeTimeseries, reporting, discover, observability, maps, dataVisualizer, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega, data | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternField" text="IndexPatternField"/> | dataViews, discover, maps, dataVisualizer, lens, indexPatternFieldEditor, securitySolution, indexPatternEditor, indexPatternManagement, inputControlVis, visDefaultEditor, visTypeTimeseries | - | -| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | dataViews, visTypeTimeseries, reporting, discover, observability, infra, maps, dataVisualizer, ml, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega | - | +| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | dataViews, visTypeTimeseries, reporting, discover, observability, maps, dataVisualizer, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega | - | | <DocLink id="kibLicensingPluginApi" section="def-public.PublicLicense.mode" text="mode"/> | apm, security, securitySolution | - | | <DocLink id="kibLicensingPluginApi" section="def-server.PublicLicense.mode" text="mode"/> | apm, security, securitySolution | - | | <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authc" text="authc"/> | reporting, encryptedSavedObjects, actions, ml, dataEnhanced, logstash, securitySolution | - | | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | dashboard, lens, maps, ml, securitySolution, security, visualize | - | | <DocLink id="kibCorePluginApi" section="def-public.AppLeaveHandler" text="AppLeaveHandler"/> | securitySolution | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsService" text="IndexPatternsService"/> | dataViews, visTypeTimeseries, maps, lens, discover, data | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, discover, infra, observability, savedObjects, security, visualizations, dashboard, lens, maps, ml, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, discover, ml, transform, canvas | - | +| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, discover, observability, savedObjects, security, visualizations, dashboard, lens, maps, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | +| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, discover, transform, canvas | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternSpec" text="IndexPatternSpec"/> | dataViews, observability, indexPatternEditor, apm | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternType" text="IndexPatternType"/> | dataViews | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternListItem" text="IndexPatternListItem"/> | dataViews, indexPatternManagement | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, discover, ml, transform, canvas, data | - | +| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, discover, transform, canvas, data | - | | <DocLink id="kibDataPluginApi" section="def-common.IIndexPatternsApiClient" text="IIndexPatternsApiClient"/> | dataViews, data | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternFieldMap" text="IndexPatternFieldMap"/> | dataViews, data | - | | <DocLink id="kibDataPluginApi" section="def-common.DataViewSpec.intervalName" text="intervalName"/> | dataViews | - | @@ -42,38 +42,39 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-common.INDEX_PATTERN_SAVED_OBJECT_TYPE" text="INDEX_PATTERN_SAVED_OBJECT_TYPE"/> | dataViews, visualizations, dashboard, data | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternType" text="IndexPatternType"/> | dataViews, data | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsService" text="IndexPatternsService"/> | dataViews, visTypeTimeseries, maps, lens, discover, data | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, discover, infra, observability, savedObjects, security, visualizations, dashboard, lens, maps, ml, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | +| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, discover, observability, savedObjects, security, visualizations, dashboard, lens, maps, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | +| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | dataViews, discover, dashboard, lens, visualize | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternListItem" text="IndexPatternListItem"/> | dataViews, indexPatternManagement, data | - | -| <DocLink id="kibDataPluginApi" section="def-server.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, discover, ml, transform, canvas | - | +| <DocLink id="kibDataPluginApi" section="def-server.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, discover, transform, canvas | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternsService" text="IndexPatternsService"/> | dataViews, visTypeTimeseries, maps, lens, discover | - | | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | fleet, indexPatternFieldEditor, discover, dashboard, lens, ml, stackAlerts, indexPatternManagement, visTypePie, visTypeTable, visTypeTimeseries, visTypeXy, visTypeVislib | - | | <DocLink id="kibDataPluginApi" section="def-server.DataPluginStart.fieldFormats" text="fieldFormats"/> | reporting, visTypeTimeseries | - | | <DocLink id="kibDataViewsPluginApi" section="def-server.DataViewsServerPluginStart.indexPatternsServiceFactory" text="indexPatternsServiceFactory"/> | data, lens, visTypeTimeseries, infra, maps, visTypeTimelion | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.settings" text="settings"/> | dashboard, maps, graph, visualize | - | | <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.license$" text="license$"/> | spaces, security, reporting, actions, alerting, ml, fleet, remoteClusters, graph, indexLifecycleManagement, maps, painlessLab, rollup, searchprofiler, snapshotRestore, transform, upgradeAssistant | - | +| <DocLink id="kibDataViewsPluginApi" section="def-public.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | discover, dashboard, lens, visualize | - | | <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsMigrationLogger.warning" text="warning"/> | lens, dashboard | - | | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | discover | - | | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | discover | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectSaveModal" text="SavedObjectSaveModal"/> | embeddable, presentationUtil, discover, dashboard, graph | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectLoader" text="SavedObjectLoader"/> | discover, visualizations, dashboard | - | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | discover, savedObjectsTaggingOss, visualizations, dashboard, visualize, visDefaultEditor | - | +| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | savedObjectsTaggingOss, discover, visualizations, dashboard | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.SavedObjectClass" text="SavedObjectClass"/> | discover, visualizations, dashboard | - | | <DocLink id="kibUiActionsPluginApi" section="def-public.UiActionsService.executeTriggerActions" text="executeTriggerActions"/> | data, discover, embeddable | - | | <DocLink id="kibCorePluginApi" section="def-public.UiSettingsParams.metric" text="metric"/> | advancedSettings, discover | - | | <DocLink id="kibCorePluginApi" section="def-server.UiSettingsParams.metric" text="metric"/> | advancedSettings, discover | - | -| <DocLink id="kibSharePluginApi" section="def-public.LocatorPublic.getUrl" text="getUrl"/> | ml, infra, reporting, ingestPipelines | - | -| <DocLink id="kibSharePluginApi" section="def-common.LocatorPublic.getUrl" text="getUrl"/> | ml, infra, reporting, ingestPipelines | - | | <DocLink id="kibDiscoverPluginApi" section="def-public.DiscoverStart.urlGenerator" text="urlGenerator"/> | observability, osquery | - | | <DocLink id="kibFeaturesPluginApi" section="def-common.FeatureElasticsearchPrivileges.requiredRoles" text="requiredRoles"/> | security | - | | <DocLink id="kibFeaturesPluginApi" section="def-server.FeatureElasticsearchPrivileges.requiredRoles" text="requiredRoles"/> | security | - | | <DocLink id="kibLicensingPluginApi" section="def-public.LicensingPluginSetup.license$" text="license$"/> | security, licenseManagement, ml, fleet, apm, reporting, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher | - | | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.appBasePath" text="appBasePath"/> | management, fleet, security, kibanaOverview | - | -| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authz" text="authz"/> | actions, ml, enterpriseSearch, savedObjectsTagging | - | -| <DocLink id="kibCorePluginApi" section="def-public.IHttpFetchError.req" text="req"/> | ml | - | +| <DocLink id="kibDiscoverPluginApi" section="def-public.__LEGACY" text="__LEGACY"/> | visualizations | - | | <DocLink id="kibCorePluginApi" section="def-public.SavedObjectsImportSuccess.createNewCopy" text="createNewCopy"/> | spaces, savedObjectsManagement | - | | <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsImportSuccess.createNewCopy" text="createNewCopy"/> | spaces, savedObjectsManagement | - | | <DocLink id="kibDataPluginApi" section="def-public.SearchSourceFields.fieldsFromSource" text="fieldsFromSource"/> | reporting | - | | <DocLink id="kibDataPluginApi" section="def-common.SearchSourceFields.fieldsFromSource" text="fieldsFromSource"/> | reporting | - | +| <DocLink id="kibSharePluginApi" section="def-public.LocatorPublic.getUrl" text="getUrl"/> | ml, infra, reporting, ingestPipelines | - | +| <DocLink id="kibSharePluginApi" section="def-common.LocatorPublic.getUrl" text="getUrl"/> | ml, infra, reporting, ingestPipelines | - | | <DocLink id="kibHomePluginApi" section="def-public.HomePublicPluginSetup.environment" text="environment"/> | cloud, apm | - | | <DocLink id="kibCorePluginApi" section="def-public.CoreSetup.injectedMetadata" text="injectedMetadata"/> | visTypeVega | - | | <DocLink id="kibCorePluginApi" section="def-public.CoreStart.injectedMetadata" text="injectedMetadata"/> | monitoring, visTypeVega | - | @@ -89,6 +90,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibExpressionsPluginApi" section="def-common.ExpressionsServiceSetup.getFunctions" text="getFunctions"/> | canvas | - | | <DocLink id="kibExpressionsPluginApi" section="def-common.ExpressionsServiceSetup.getTypes" text="getTypes"/> | canvas | - | | <DocLink id="kibExpressionsPluginApi" section="def-server.ExpressionFunctionDefinition.context" text="context"/> | canvas, visTypeXy | - | +| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authz" text="authz"/> | actions, ml, enterpriseSearch, savedObjectsTagging | - | +| <DocLink id="kibCorePluginApi" section="def-public.IHttpFetchError.req" text="req"/> | ml | - | | <DocLink id="kibSecurityPluginApi" section="def-server.LegacyAuditLogger" text="LegacyAuditLogger"/> | encryptedSavedObjects, actions, alerting | - | | <DocLink id="kibTaskManagerPluginApi" section="def-server.TaskManagerSetupContract.index" text="index"/> | actions | - | | <DocLink id="kibCorePluginApi" section="def-server.ElasticsearchServiceSetup.legacy" text="legacy"/> | console | - | @@ -100,14 +103,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | discover, visualizations, dashboard, lens, observability, timelines, maps, infra, dashboardEnhanced, discoverEnhanced, securitySolution, urlDrilldown, inputControlVis, visualize, visTypeTimelion, visTypeVega, ml, visTypeTimeseries | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | discover, visualizations, dashboard, lens, observability, timelines, maps, infra, dashboardEnhanced, discoverEnhanced, securitySolution, urlDrilldown, inputControlVis, visualize, visTypeTimelion, visTypeVega, ml, visTypeTimeseries | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | discover, visualizations, dashboard, lens, observability, timelines, maps, infra, dashboardEnhanced, discoverEnhanced, securitySolution, urlDrilldown, inputControlVis, visualize, visTypeTimelion, visTypeVega, ml, visTypeTimeseries | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | dataViews, fleet, ml, infra, monitoring, stackAlerts, indexPatternManagement | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | dataViews, fleet, ml, infra, monitoring, stackAlerts, indexPatternManagement, data | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement, data | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.DataView.intervalName" text="intervalName"/> | dataViews | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.DataView.addScriptedField" text="addScriptedField"/> | dataViews | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.DataView.removeScriptedField" text="removeScriptedField"/> | indexPatternManagement, dataViews | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.DataView.getNonScriptedFields" text="getNonScriptedFields"/> | visTypeTimeseries, graph, indexPatternManagement, dataViews | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.DataView.getScriptedFields" text="getScriptedFields"/> | dataViews, indexPatternManagement | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-server.IFieldType" text="IFieldType"/> | dataViews, fleet, ml, infra, monitoring, stackAlerts, indexPatternManagement | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-server.IFieldType" text="IFieldType"/> | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.DataView.intervalName" text="intervalName"/> | dataViews | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.DataView.addScriptedField" text="addScriptedField"/> | dataViews | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.DataView.removeScriptedField" text="removeScriptedField"/> | indexPatternManagement, dataViews | 8.1 | @@ -211,6 +214,8 @@ Safe to remove. | <DocLink id="kibDataViewsPluginApi" section="def-common.DataViewSpec.intervalName" text="intervalName"/> | | <DocLink id="kibDataViewsPluginApi" section="def-common.DataView.intervalName" text="intervalName"/> | | <DocLink id="kibDataViewsPluginApi" section="def-common.DataView.addScriptedField" text="addScriptedField"/> | +| <DocLink id="kibDiscoverPluginApi" section="def-public.LegacySavedSearch" text="LegacySavedSearch"/> | +| <DocLink id="kibDiscoverPluginApi" section="def-public.SavedSearchLoader" text="SavedSearchLoader"/> | | <DocLink id="kibExpressionsPluginApi" section="def-public.ExpressionExecutor" text="ExpressionExecutor"/> | | <DocLink id="kibExpressionsPluginApi" section="def-public.Executor.functions" text="functions"/> | | <DocLink id="kibExpressionsPluginApi" section="def-public.Executor.types" text="types"/> | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index b33ab317ca885..7ef3a75269963 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -131,10 +131,12 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter)+ 25 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.INDEX_PATTERN_SAVED_OBJECT_TYPE" text="INDEX_PATTERN_SAVED_OBJECT_TYPE"/> | [replace_index_pattern_reference.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/replace_index_pattern_reference.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [replace_index_pattern_reference.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/replace_index_pattern_reference.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [dashboard_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [dashboard_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [dashboard_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [replace_index_pattern_reference.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/replace_index_pattern_reference.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [replace_index_pattern_reference.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/replace_index_pattern_reference.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [dashboard_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [dashboard_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [dashboard_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPatternsContract), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPatternsContract), [make_default_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts#:~:text=IndexPatternsContract), [make_default_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts#:~:text=IndexPatternsContract), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPatternsContract), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPatternsContract)+ 2 more | - | +| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [load_saved_dashboard_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/load_saved_dashboard_state.ts#:~:text=ensureDefaultDataView), [load_saved_dashboard_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/load_saved_dashboard_state.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern)+ 6 more | - | | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter)+ 25 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [sync_dashboard_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_index_patterns.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=IndexPattern) | - | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter)+ 25 more | 8.1 | +| <DocLink id="kibDataViewsPluginApi" section="def-public.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [load_saved_dashboard_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/load_saved_dashboard_state.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectSaveModal" text="SavedObjectSaveModal"/> | [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/top_nav/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/top_nav/save_modal.tsx#:~:text=SavedObjectSaveModal) | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectLoader" text="SavedObjectLoader"/> | [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObjectLoader), [saved_dashboards.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboards.ts#:~:text=SavedObjectLoader), [saved_dashboards.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboards.ts#:~:text=SavedObjectLoader), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=SavedObjectLoader), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/plugin.tsx#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/plugin.tsx#:~:text=SavedObjectLoader), [make_default_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts#:~:text=SavedObjectLoader), [make_default_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts#:~:text=SavedObjectLoader), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/url_generator.ts#:~:text=SavedObjectLoader)+ 3 more | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObject), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObject), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObject), [dashboard_tagging.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/dashboard_tagging.ts#:~:text=SavedObject), [dashboard_tagging.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/dashboard_tagging.ts#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject) | - | @@ -222,6 +224,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternType" text="IndexPatternType"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternType) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsService" text="IndexPatternsService"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternsService) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternsContract) | - | +| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [data_views.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_views.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternListItem" text="IndexPatternListItem"/> | [data_views.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_views.ts#:~:text=IndexPatternListItem), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternListItem) | - | | <DocLink id="kibDataPluginApi" section="def-common.DataView.intervalName" text="intervalName"/> | [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [update_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/routes/update_index_pattern.ts#:~:text=intervalName), [update_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/routes/update_index_pattern.ts#:~:text=intervalName) | 8.1 | @@ -261,8 +264,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsService" text="IndexPatternsService"/> | [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService)+ 6 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 50 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 354 more | - | +| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 34 more | - | +| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 378 more | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField)+ 192 more | - | | <DocLink id="kibDataPluginApi" section="def-public.IndexPatternAttributes" text="IndexPatternAttributes"/> | [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes)+ 3 more | - | | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create) | - | @@ -270,24 +273,26 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [build_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/build_services.ts#:~:text=indexPatterns), [source_viewer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/source_viewer/source_viewer.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=indexPatterns) | - | | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | [histogram.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx#:~:text=fieldFormats) | - | | <DocLink id="kibDataPluginApi" section="def-public.esFilters" text="esFilters"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=esFilters), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=esFilters), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=esFilters), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=esFilters), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=esFilters), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=esFilters), [get_context_url.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/get_context_url.tsx#:~:text=esFilters), [get_context_url.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/get_context_url.tsx#:~:text=esFilters), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=esFilters), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=esFilters)+ 17 more | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 21 more | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 22 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes)+ 16 more | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField)+ 192 more | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsService" text="IndexPatternsService"/> | [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService)+ 6 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 50 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 354 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 21 more | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 34 more | - | +| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=ensureDefaultDataView), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=ensureDefaultDataView) | - | +| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 378 more | - | +| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 22 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create) | - | | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/services/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternField" text="IndexPatternField"/> | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField)+ 91 more | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternAttributes" text="IndexPatternAttributes"/> | [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes)+ 3 more | - | -| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 172 more | - | +| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 184 more | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternsService" text="IndexPatternsService"/> | [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService)+ 6 more | - | -| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 21 more | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 22 more | 8.1 | +| <DocLink id="kibDataViewsPluginApi" section="def-public.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectSaveModal" text="SavedObjectSaveModal"/> | [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal) | - | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectLoader" text="SavedObjectLoader"/> | [saved_searches.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/saved_searches.ts#:~:text=SavedObjectLoader), [saved_searches.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/saved_searches.ts#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=SavedObjectLoader) | - | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=SavedObject), [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/_saved_search.ts#:~:text=SavedObject), [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/_saved_search.ts#:~:text=SavedObject), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=SavedObject), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=SavedObject) | - | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.SavedObjectClass" text="SavedObjectClass"/> | [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/_saved_search.ts#:~:text=SavedObjectClass) | - | +| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectLoader" text="SavedObjectLoader"/> | [saved_searches.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/saved_searches.ts#:~:text=SavedObjectLoader), [saved_searches.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/saved_searches.ts#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=SavedObjectLoader) | - | +| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts#:~:text=SavedObject), [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts#:~:text=SavedObject) | - | +| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.SavedObjectClass" text="SavedObjectClass"/> | [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts#:~:text=SavedObjectClass) | - | | <DocLink id="kibUiActionsPluginApi" section="def-public.UiActionsService.executeTriggerActions" text="executeTriggerActions"/> | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=executeTriggerActions), [search_embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts#:~:text=executeTriggerActions), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=executeTriggerActions), [search_embeddable_factory.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/embeddable/search_embeddable_factory.d.ts#:~:text=executeTriggerActions) | - | | <DocLink id="kibCorePluginApi" section="def-public.UiSettingsParams.metric" text="metric"/> | [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric) | - | | <DocLink id="kibCorePluginApi" section="def-server.UiSettingsParams.metric" text="metric"/> | [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric) | - | @@ -467,21 +472,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [log_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts#:~:text=IndexPatternsContract), [log_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts#:~:text=IndexPatternsContract), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPatternsContract), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPatternsContract), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPatternsContract), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPatternsContract)+ 12 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPattern), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPattern), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPattern), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern)+ 14 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [kuery_bar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx#:~:text=IIndexPattern), [kuery_bar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx#:~:text=IIndexPattern), [toolbar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx#:~:text=IIndexPattern), [toolbar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=IIndexPattern), [use_metrics_explorer_data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts#:~:text=IIndexPattern), [use_metrics_explorer_data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts#:~:text=IIndexPattern)+ 34 more | - | | <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [custom_metric_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx#:~:text=IFieldType), [custom_metric_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx#:~:text=IFieldType), [custom_field_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx#:~:text=IFieldType), [custom_field_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx#:~:text=IFieldType), [waffle_group_by_controls.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx#:~:text=IFieldType), [waffle_group_by_controls.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx#:~:text=IFieldType), [metric.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx#:~:text=IFieldType), [metric.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx#:~:text=IFieldType)+ 46 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [editor.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx#:~:text=indexPatterns), [log_stream.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx#:~:text=indexPatterns), [log_stream.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx#:~:text=indexPatterns), [logs_overview_fetchers.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts#:~:text=indexPatterns), [redirect_to_node_logs.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx#:~:text=indexPatterns), [use_kibana_index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/hooks/use_kibana_index_patterns.ts#:~:text=indexPatterns), [page_providers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/page_providers.tsx#:~:text=indexPatterns), [logs_overview_fetches.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts#:~:text=indexPatterns) | - | | <DocLink id="kibDataPluginApi" section="def-public.esKuery" text="esKuery"/> | [kuery_bar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx#:~:text=esKuery), [kuery_bar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx#:~:text=esKuery), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=esKuery), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=esKuery), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=esKuery), [use_waffle_filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts#:~:text=esKuery), [use_waffle_filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts#:~:text=esKuery) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-public.esQuery" text="esQuery"/> | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts#:~:text=esQuery), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts#:~:text=esQuery), [log_filter_state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts#:~:text=esQuery), [log_filter_state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts#:~:text=esQuery), [log_filter_state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts#:~:text=esQuery) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [log_stream_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx#:~:text=Filter), [log_stream_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [custom_metric_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx#:~:text=IFieldType), [custom_metric_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx#:~:text=IFieldType), [custom_field_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx#:~:text=IFieldType), [custom_field_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx#:~:text=IFieldType), [waffle_group_by_controls.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx#:~:text=IFieldType), [waffle_group_by_controls.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx#:~:text=IFieldType), [metric.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx#:~:text=IFieldType), [metric.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx#:~:text=IFieldType)+ 102 more | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [kuery_bar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx#:~:text=IIndexPattern), [kuery_bar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx#:~:text=IIndexPattern), [toolbar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx#:~:text=IIndexPattern), [toolbar.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/utils/kuery.ts#:~:text=IIndexPattern), [use_metrics_explorer_data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts#:~:text=IIndexPattern), [use_metrics_explorer_data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts#:~:text=IIndexPattern)+ 78 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPatternsContract), [log_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts#:~:text=IndexPatternsContract), [log_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts#:~:text=IndexPatternsContract), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPatternsContract), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPatternsContract), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPatternsContract), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPatternsContract)+ 12 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPattern), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPattern), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPattern), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern)+ 14 more | - | | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [log_stream_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx#:~:text=Filter), [log_stream_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IFieldType" text="IFieldType"/> | [custom_metric_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx#:~:text=IFieldType), [custom_metric_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx#:~:text=IFieldType), [custom_field_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx#:~:text=IFieldType), [custom_field_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx#:~:text=IFieldType), [waffle_group_by_controls.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx#:~:text=IFieldType), [waffle_group_by_controls.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx#:~:text=IFieldType), [metric.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx#:~:text=IFieldType), [metric.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx#:~:text=IFieldType)+ 46 more | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [resolved_log_source_configuration.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/log_sources/resolved_log_source_configuration.ts#:~:text=IndexPattern), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPattern), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/common/dependency_mocks/index_patterns.ts#:~:text=IndexPattern), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPattern), [index_patterns.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/target/types/common/dependency_mocks/index_patterns.d.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern), [validation_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/settings/validation_errors.ts#:~:text=IndexPattern)+ 2 more | - | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [log_stream_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx#:~:text=Filter), [log_stream_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter), [use_dataset_filtering.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_dataset_filtering.ts#:~:text=Filter) | 8.1 | | <DocLink id="kibDataViewsPluginApi" section="def-server.DataViewsServerPluginStart.indexPatternsServiceFactory" text="indexPatternsServiceFactory"/> | [kibana_framework_adapter.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts#:~:text=indexPatternsServiceFactory), [log_entries_search_strategy.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts#:~:text=indexPatternsServiceFactory), [log_entry_search_strategy.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts#:~:text=indexPatternsServiceFactory) | - | | <DocLink id="kibSharePluginApi" section="def-public.LocatorPublic.getUrl" text="getUrl"/> | [module_list_card.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/components/logging/log_analysis_setup/setup_flyout/module_list_card.tsx#:~:text=getUrl) | - | @@ -555,12 +553,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField)+ 8 more | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsService" text="IndexPatternsService"/> | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract)+ 20 more | - | +| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=ensureDefaultDataView), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPattern), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPattern)+ 36 more | - | | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter)+ 16 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternField" text="IndexPatternField"/> | [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField) | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPattern), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPattern)+ 13 more | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternsService" text="IndexPatternsService"/> | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService) | - | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter)+ 16 more | 8.1 | +| <DocLink id="kibDataViewsPluginApi" section="def-public.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibDataViewsPluginApi" section="def-server.DataViewsServerPluginStart.indexPatternsServiceFactory" text="indexPatternsServiceFactory"/> | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=indexPatternsServiceFactory), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=indexPatternsServiceFactory) | - | | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | - | | <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsMigrationLogger.warning" text="warning"/> | [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning), [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning) | - | @@ -625,23 +625,10 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [dependency_cache.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/dependency_cache.ts#:~:text=IndexPatternsContract), [dependency_cache.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/dependency_cache.ts#:~:text=IndexPatternsContract), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternsContract), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternsContract), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternsContract), [resolvers.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/routing/resolvers.ts#:~:text=IndexPatternsContract), [resolvers.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/routing/resolvers.ts#:~:text=IndexPatternsContract), [preconfigured_job_redirect.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts#:~:text=IndexPatternsContract), [preconfigured_job_redirect.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts#:~:text=IndexPatternsContract), [load_new_job_capabilities.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts#:~:text=IndexPatternsContract)+ 32 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [chart_loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts#:~:text=IndexPattern), [chart_loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/types.ts#:~:text=IndexPattern), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=IndexPattern), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [field_format_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/field_format_service.ts#:~:text=IndexPattern)+ 130 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IIndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IIndexPattern), [new_job_capabilities_service_analytics.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts#:~:text=IIndexPattern), [new_job_capabilities_service_analytics.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts#:~:text=IIndexPattern), [data_recognizer.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts#:~:text=IIndexPattern), [data_recognizer.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts#:~:text=IIndexPattern), [new_job_capabilities_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts#:~:text=IIndexPattern), [new_job_capabilities_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts#:~:text=IIndexPattern), [load_new_job_capabilities.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts#:~:text=IIndexPattern), [load_new_job_capabilities.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts#:~:text=IIndexPattern)+ 24 more | - | -| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.ts#:~:text=IFieldType), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType) | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternAttributes" text="IndexPatternAttributes"/> | [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternAttributes), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternAttributes), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=IndexPatternAttributes), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [data_recognizer.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=IndexPatternAttributes), [data_recognizer.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=IndexPatternAttributes), [kibana.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/common/types/kibana.ts#:~:text=IndexPatternAttributes)+ 3 more | - | | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [index_data_visualizer.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx#:~:text=indexPatterns), [file_datavisualizer.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx#:~:text=indexPatterns), [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/app.tsx#:~:text=indexPatterns), [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/app.tsx#:~:text=indexPatterns), [import_jobs_flyout.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx#:~:text=indexPatterns), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=indexPatterns) | - | | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | [dependency_cache.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/dependency_cache.ts#:~:text=fieldFormats), [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/app.tsx#:~:text=fieldFormats), [dependency_cache.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/target/types/public/application/util/dependency_cache.d.ts#:~:text=fieldFormats) | - | | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [apply_influencer_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx#:~:text=Filter), [apply_influencer_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx#:~:text=Filter), [apply_entity_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_entity_filters_action.tsx#:~:text=Filter), [apply_entity_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_entity_filters_action.tsx#:~:text=Filter) | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.ts#:~:text=IFieldType), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType)+ 8 more | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IIndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IIndexPattern), [new_job_capabilities_service_analytics.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts#:~:text=IIndexPattern), [new_job_capabilities_service_analytics.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts#:~:text=IIndexPattern), [data_recognizer.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts#:~:text=IIndexPattern), [data_recognizer.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts#:~:text=IIndexPattern), [new_job_capabilities_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts#:~:text=IIndexPattern), [new_job_capabilities_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts#:~:text=IIndexPattern), [load_new_job_capabilities.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts#:~:text=IIndexPattern), [load_new_job_capabilities.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts#:~:text=IIndexPattern)+ 58 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternAttributes), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternAttributes), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=IndexPatternAttributes), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [data_recognizer.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=IndexPatternAttributes), [data_recognizer.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=IndexPatternAttributes), [kibana.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/common/types/kibana.ts#:~:text=IndexPatternAttributes)+ 16 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [dependency_cache.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/dependency_cache.ts#:~:text=IndexPatternsContract), [dependency_cache.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/dependency_cache.ts#:~:text=IndexPatternsContract), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternsContract), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternsContract), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternsContract), [resolvers.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/routing/resolvers.ts#:~:text=IndexPatternsContract), [resolvers.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/routing/resolvers.ts#:~:text=IndexPatternsContract), [preconfigured_job_redirect.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts#:~:text=IndexPatternsContract), [preconfigured_job_redirect.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts#:~:text=IndexPatternsContract), [load_new_job_capabilities.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts#:~:text=IndexPatternsContract)+ 32 more | - | -| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [chart_loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts#:~:text=IndexPattern), [chart_loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/types.ts#:~:text=IndexPattern), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=IndexPattern), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [field_format_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/field_format_service.ts#:~:text=IndexPattern)+ 130 more | - | | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [apply_influencer_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx#:~:text=Filter), [apply_influencer_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx#:~:text=Filter), [apply_entity_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_entity_filters_action.tsx#:~:text=Filter), [apply_entity_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_entity_filters_action.tsx#:~:text=Filter) | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-server.IFieldType" text="IFieldType"/> | [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/data_grid/common.ts#:~:text=IFieldType), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.ts#:~:text=IFieldType), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType), [field_types_utils.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts#:~:text=IFieldType) | 8.1 | -| <DocLink id="kibDataPluginApi" section="def-server.IndexPatternAttributes" text="IndexPatternAttributes"/> | [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternAttributes), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPatternAttributes), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=IndexPatternAttributes), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [rollup.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=IndexPatternAttributes), [data_recognizer.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=IndexPatternAttributes), [data_recognizer.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=IndexPatternAttributes), [kibana.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/common/types/kibana.ts#:~:text=IndexPatternAttributes)+ 3 more | - | -| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [chart_loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts#:~:text=IndexPattern), [chart_loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/types.ts#:~:text=IndexPattern), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=IndexPattern), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [index_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/util/index_utils.ts#:~:text=IndexPattern), [field_format_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/services/field_format_service.ts#:~:text=IndexPattern)+ 60 more | - | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [apply_influencer_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx#:~:text=Filter), [apply_influencer_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx#:~:text=Filter), [apply_entity_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_entity_filters_action.tsx#:~:text=Filter), [apply_entity_filters_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/ui_actions/apply_entity_filters_action.tsx#:~:text=Filter) | 8.1 | | <DocLink id="kibSharePluginApi" section="def-public.LocatorPublic.getUrl" text="getUrl"/> | [use_create_url.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts#:~:text=getUrl), [use_create_url.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts#:~:text=getUrl), [main_tabs.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/navigation_menu/main_tabs.tsx#:~:text=getUrl), [anomaly_detection_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx#:~:text=getUrl), [anomaly_detection_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx#:~:text=getUrl), [use_view_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/use_view_action.tsx#:~:text=getUrl), [use_map_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_map/use_map_action.tsx#:~:text=getUrl), [analytics_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/overview/components/analytics_panel/analytics_panel.tsx#:~:text=getUrl), [page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/pages/job_type/page.tsx#:~:text=getUrl), [page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx#:~:text=getUrl)+ 14 more | - | | <DocLink id="kibSharePluginApi" section="def-common.LocatorPublic.getUrl" text="getUrl"/> | [use_create_url.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts#:~:text=getUrl), [use_create_url.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts#:~:text=getUrl), [main_tabs.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/navigation_menu/main_tabs.tsx#:~:text=getUrl), [anomaly_detection_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx#:~:text=getUrl), [anomaly_detection_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx#:~:text=getUrl), [use_view_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/use_view_action.tsx#:~:text=getUrl), [use_map_action.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_map/use_map_action.tsx#:~:text=getUrl), [analytics_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/overview/components/analytics_panel/analytics_panel.tsx#:~:text=getUrl), [page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/pages/job_type/page.tsx#:~:text=getUrl), [page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx#:~:text=getUrl)+ 14 more | - | @@ -979,7 +966,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-common.AggConfig.toJSON" text="toJSON"/> | [reducers.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/state/reducers.ts#:~:text=toJSON), [reducers.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/state/reducers.ts#:~:text=toJSON), [reducers.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/state/reducers.ts#:~:text=toJSON), [sidebar.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx#:~:text=toJSON) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IndexPatternField" text="IndexPatternField"/> | [agg_type_field_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/agg_filters/agg_type_field_filters.ts#:~:text=IndexPatternField), [agg_type_field_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/agg_filters/agg_type_field_filters.ts#:~:text=IndexPatternField), [agg_type_field_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/agg_filters/agg_type_field_filters.ts#:~:text=IndexPatternField), [agg_param_props.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_param_props.ts#:~:text=IndexPatternField), [agg_param_props.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_param_props.ts#:~:text=IndexPatternField), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/controls/field.tsx#:~:text=IndexPatternField), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/controls/field.tsx#:~:text=IndexPatternField), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/controls/field.tsx#:~:text=IndexPatternField), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/controls/field.tsx#:~:text=IndexPatternField), [top_field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/controls/top_field.tsx#:~:text=IndexPatternField)+ 14 more | - | | <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [agg_type_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/agg_filters/agg_type_filters.ts#:~:text=IndexPattern), [agg_type_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/agg_filters/agg_type_filters.ts#:~:text=IndexPattern), [agg_type_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/agg_filters/agg_type_filters.ts#:~:text=IndexPattern), [editor_config.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/utils/editor_config.ts#:~:text=IndexPattern), [editor_config.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/utils/editor_config.ts#:~:text=IndexPattern), [agg_params_helper.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_params_helper.ts#:~:text=IndexPattern), [agg_params_helper.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_params_helper.ts#:~:text=IndexPattern), [agg_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_select.tsx#:~:text=IndexPattern), [agg_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_select.tsx#:~:text=IndexPattern), [agg_params.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/agg_params.tsx#:~:text=IndexPattern)+ 7 more | - | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [sidebar_title.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx#:~:text=SavedObject), [sidebar_title.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx#:~:text=SavedObject), [sidebar_title.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx#:~:text=SavedObject), [sidebar.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx#:~:text=SavedObject), [sidebar.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx#:~:text=SavedObject), [sidebar.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar.d.ts#:~:text=SavedObject), [sidebar.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar.d.ts#:~:text=SavedObject), [sidebar_title.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar_title.d.ts#:~:text=SavedObject), [sidebar_title.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar_title.d.ts#:~:text=SavedObject), [sidebar_title.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar_title.d.ts#:~:text=SavedObject) | - | @@ -1100,7 +1086,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-common.AggConfig.toJSON" text="toJSON"/> | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=toJSON) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern) | - | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter) | 8.1 | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectLoader" text="SavedObjectLoader"/> | [find_list_items.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts#:~:text=SavedObjectLoader), [find_list_items.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/services.ts#:~:text=SavedObjectLoader), [services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/services.ts#:~:text=SavedObjectLoader) | - | +| <DocLink id="kibDiscoverPluginApi" section="def-public.__LEGACY" text="__LEGACY"/> | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=__LEGACY), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=__LEGACY) | - | +| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectLoader" text="SavedObjectLoader"/> | [find_list_items.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts#:~:text=SavedObjectLoader), [find_list_items.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader) | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject) | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.SavedObjectClass" text="SavedObjectClass"/> | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObjectClass) | - | @@ -1114,12 +1101,13 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=indexPatterns), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=indexPatterns), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=indexPatterns), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=indexPatterns) | - | | <DocLink id="kibDataPluginApi" section="def-public.esFilters" text="esFilters"/> | [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_visualize_app_state.tsx#:~:text=esFilters), [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_visualize_app_state.tsx#:~:text=esFilters), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=esFilters), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=esFilters), [get_visualize_list_item_link.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/get_visualize_list_item_link.test.ts#:~:text=esFilters), [get_visualize_list_item_link.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/get_visualize_list_item_link.test.ts#:~:text=esFilters) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/utils.ts#:~:text=Filter), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/utils.ts#:~:text=Filter), [use_linked_search_updates.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_linked_search_updates.ts#:~:text=Filter), [use_linked_search_updates.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_linked_search_updates.ts#:~:text=Filter), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=Filter), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=Filter)+ 6 more | 8.1 | +| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=ensureDefaultDataView), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern) | - | | <DocLink id="kibDataPluginApi" section="def-common.isFilterPinned" text="isFilterPinned"/> | [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/common/locator.ts#:~:text=isFilterPinned), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/common/locator.ts#:~:text=isFilterPinned), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/common/locator.ts#:~:text=isFilterPinned) | 8.1 | | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/utils.ts#:~:text=Filter), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/utils.ts#:~:text=Filter), [use_linked_search_updates.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_linked_search_updates.ts#:~:text=Filter), [use_linked_search_updates.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_linked_search_updates.ts#:~:text=Filter), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=Filter), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=Filter)+ 6 more | 8.1 | | <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=IndexPattern) | - | | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=Filter), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/utils.ts#:~:text=Filter), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/utils.ts#:~:text=Filter), [use_linked_search_updates.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_linked_search_updates.ts#:~:text=Filter), [use_linked_search_updates.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/use/use_linked_search_updates.ts#:~:text=Filter), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=Filter), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=Filter)+ 6 more | 8.1 | -| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=SavedObject), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=SavedObject), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=SavedObject), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/types.ts#:~:text=SavedObject), [get_visualization_instance.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/get_visualization_instance.ts#:~:text=SavedObject), [get_visualization_instance.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/utils/get_visualization_instance.ts#:~:text=SavedObject), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=SavedObject), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=SavedObject), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=SavedObject), [types.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/types.d.ts#:~:text=SavedObject)+ 3 more | - | +| <DocLink id="kibDataViewsPluginApi" section="def-public.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/plugin.ts#:~:text=ensureDefaultDataView) | - | | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.settings" text="settings"/> | [visualize_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_listing.tsx#:~:text=settings), [visualize_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_listing.tsx#:~:text=settings) | - | | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/public/application/index.tsx#:~:text=onAppLeave), [app.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/app.d.ts#:~:text=onAppLeave), [index.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/index.d.ts#:~:text=onAppLeave), [visualize_editor_common.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/components/visualize_editor_common.d.ts#:~:text=onAppLeave), [visualize_top_nav.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualize/target/types/public/application/components/visualize_top_nav.d.ts#:~:text=onAppLeave) | - | diff --git a/api_docs/discover.json b/api_docs/discover.json index bab87863a903b..2e8dd6a450e7a 100644 --- a/api_docs/discover.json +++ b/api_docs/discover.json @@ -5,35 +5,157 @@ "functions": [ { "parentPluginId": "discover", - "id": "def-public.createSavedSearchesLoader", + "id": "def-public.getSavedSearch", "type": "Function", "tags": [], - "label": "createSavedSearchesLoader", + "label": "getSavedSearch", "description": [], "signature": [ - "({ savedObjectsClient, savedObjects }: Services) => ", + "(savedSearchId: string | undefined, dependencies: GetSavedSearchDependencies) => Promise<", { - "pluginId": "savedObjects", + "pluginId": "discover", "scope": "public", - "docId": "kibSavedObjectsPluginApi", - "section": "def-public.SavedObjectLoader", - "text": "SavedObjectLoader" + "docId": "kibDiscoverPluginApi", + "section": "def-public.SavedSearch", + "text": "SavedSearch" + }, + ">" + ], + "path": "src/plugins/discover/public/saved_searches/get_saved_searches.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearch.$1", + "type": "string", + "tags": [], + "label": "savedSearchId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/get_saved_searches.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearch.$2", + "type": "Object", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "GetSavedSearchDependencies" + ], + "path": "src/plugins/discover/public/saved_searches/get_saved_searches.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearchFullPathUrl", + "type": "Function", + "tags": [], + "label": "getSavedSearchFullPathUrl", + "description": [], + "signature": [ + "(id?: string | undefined) => string" + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearchFullPathUrl.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearchUrl", + "type": "Function", + "tags": [], + "label": "getSavedSearchUrl", + "description": [], + "signature": [ + "(id?: string | undefined) => string" + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearchUrl.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", + "deprecated": false, + "isRequired": false } ], - "path": "src/plugins/discover/public/saved_searches/saved_searches.ts", + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.getSavedSearchUrlConflictMessage", + "type": "Function", + "tags": [], + "label": "getSavedSearchUrlConflictMessage", + "description": [], + "signature": [ + "(savedSearch: ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.SavedSearch", + "text": "SavedSearch" + }, + ") => Promise<string>" + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", "deprecated": false, "children": [ { "parentPluginId": "discover", - "id": "def-public.createSavedSearchesLoader.$1", + "id": "def-public.getSavedSearchUrlConflictMessage.$1", "type": "Object", "tags": [], - "label": "{ savedObjectsClient, savedObjects }", + "label": "savedSearch", "description": [], "signature": [ - "Services" + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.SavedSearch", + "text": "SavedSearch" + } ], - "path": "src/plugins/discover/public/saved_searches/saved_searches.ts", + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", "deprecated": false, "isRequired": true } @@ -58,6 +180,51 @@ "children": [], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.throwErrorOnSavedSearchUrlConflict", + "type": "Function", + "tags": [], + "label": "throwErrorOnSavedSearchUrlConflict", + "description": [], + "signature": [ + "(savedSearch: ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.SavedSearch", + "text": "SavedSearch" + }, + ") => Promise<void>" + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.throwErrorOnSavedSearchUrlConflict.$1", + "type": "Object", + "tags": [], + "label": "savedSearch", + "description": [], + "signature": [ + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.SavedSearch", + "text": "SavedSearch" + } + ], + "path": "src/plugins/discover/public/saved_searches/saved_searches_utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ @@ -602,181 +769,341 @@ }, { "parentPluginId": "discover", - "id": "def-public.SavedSearch", + "id": "def-public.LegacySavedSearch", "type": "Interface", - "tags": [], - "label": "SavedSearch", + "tags": [ + "deprecated" + ], + "label": "LegacySavedSearch", "description": [], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false, + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": true, + "references": [], "children": [ { "parentPluginId": "discover", - "id": "def-public.SavedSearch.id", + "id": "def-public.LegacySavedSearch.id", "type": "string", "tags": [], "label": "id", "description": [], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false }, { "parentPluginId": "discover", - "id": "def-public.SavedSearch.title", + "id": "def-public.LegacySavedSearch.title", "type": "string", "tags": [], "label": "title", "description": [], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false }, { "parentPluginId": "discover", - "id": "def-public.SavedSearch.searchSource", + "id": "def-public.LegacySavedSearch.searchSource", "type": "Object", "tags": [], "label": "searchSource", "description": [], "signature": [ + "{ create: () => ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", "section": "def-common.SearchSource", "text": "SearchSource" - } - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false - }, - { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.description", - "type": "string", - "tags": [], - "label": "description", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false - }, - { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.columns", - "type": "Array", - "tags": [], - "label": "columns", - "description": [], - "signature": [ - "string[]" - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false - }, - { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.sort", - "type": "Array", - "tags": [], - "label": "sort", - "description": [], - "signature": [ - "SortOrder", - "[]" - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false - }, - { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.grid", - "type": "Object", - "tags": [], - "label": "grid", - "description": [], - "signature": [ - "DiscoverGridSettings" - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false - }, - { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.destroy", - "type": "Function", - "tags": [], - "label": "destroy", - "description": [], - "signature": [ - "() => void" - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.save", - "type": "Function", - "tags": [], - "label": "save", - "description": [], - "signature": [ - "(saveOptions: ", + }, + "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", { - "pluginId": "savedObjects", - "scope": "public", - "docId": "kibSavedObjectsPluginApi", - "section": "def-public.SavedObjectSaveOpts", - "text": "SavedObjectSaveOpts" + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" }, - ") => Promise<string>" - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false, - "children": [ + "[K]) => ", { - "parentPluginId": "discover", - "id": "def-public.SavedSearch.save.$1", - "type": "Object", - "tags": [], - "label": "saveOptions", - "description": [], - "signature": [ - { - "pluginId": "savedObjects", - "scope": "public", - "docId": "kibSavedObjectsPluginApi", - "section": "def-public.SavedObjectSaveOpts", - "text": "SavedObjectSaveOpts" - } - ], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; removeField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; setFields: (newFields: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; getId: () => string; getFields: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "; getField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "[K]; getOwnField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "[K]; createCopy: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; createChild: (options?: {}) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; setParent: (parent?: Pick<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + ", \"create\" | \"history\" | \"setPreferredSearchStrategyId\" | \"setField\" | \"removeField\" | \"setFields\" | \"getId\" | \"getFields\" | \"getField\" | \"getOwnField\" | \"createCopy\" | \"createChild\" | \"setParent\" | \"getParent\" | \"fetch$\" | \"fetch\" | \"onRequestStart\" | \"getSearchRequestBody\" | \"destroy\" | \"getSerializedFields\" | \"serialize\"> | undefined, options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceOptions", + "text": "SearchSourceOptions" + }, + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; getParent: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + " | undefined; fetch$: (options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchOptions", + "text": "ISearchOptions" + }, + ") => ", + "Observable", + "<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.IKibanaSearchResponse", + "text": "IKibanaSearchResponse" + }, + "<", + "SearchResponse", + "<any>>>; fetch: (options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchOptions", + "text": "ISearchOptions" + }, + ") => Promise<", + "SearchResponse", + "<any>>; onRequestStart: (handler: (searchSource: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + ", options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchOptions", + "text": "ISearchOptions" + }, + " | undefined) => Promise<unknown>) => void; getSearchRequestBody: () => any; destroy: () => void; getSerializedFields: (recurse?: boolean) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "; serialize: () => { searchSourceJSON: string; references: ", + "SavedObjectReference", + "[]; }; }" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false }, { "parentPluginId": "discover", - "id": "def-public.SavedSearch.lastSavedTitle", + "id": "def-public.LegacySavedSearch.description", "type": "string", "tags": [], - "label": "lastSavedTitle", + "label": "description", "description": [], "signature": [ "string | undefined" ], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.columns", + "type": "Array", + "tags": [], + "label": "columns", + "description": [], + "signature": [ + "string[]" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.sort", + "type": "Array", + "tags": [], + "label": "sort", + "description": [], + "signature": [ + "SortOrder", + "[]" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false }, { "parentPluginId": "discover", - "id": "def-public.SavedSearch.copyOnSave", + "id": "def-public.LegacySavedSearch.grid", + "type": "Object", + "tags": [], + "label": "grid", + "description": [], + "signature": [ + "DiscoverGridSettings" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.destroy", + "type": "Function", + "tags": [], + "label": "destroy", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.save", + "type": "Function", + "tags": [], + "label": "save", + "description": [], + "signature": [ + "(saveOptions: ", + { + "pluginId": "savedObjects", + "scope": "public", + "docId": "kibSavedObjectsPluginApi", + "section": "def-public.SavedObjectSaveOpts", + "text": "SavedObjectSaveOpts" + }, + ") => Promise<string>" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.save.$1", + "type": "Object", + "tags": [], + "label": "saveOptions", + "description": [], + "signature": [ + { + "pluginId": "savedObjects", + "scope": "public", + "docId": "kibSavedObjectsPluginApi", + "section": "def-public.SavedObjectSaveOpts", + "text": "SavedObjectSaveOpts" + } + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.copyOnSave", "type": "CompoundType", "tags": [], "label": "copyOnSave", @@ -784,6 +1111,301 @@ "signature": [ "boolean | undefined" ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.LegacySavedSearch.hideChart", + "type": "CompoundType", + "tags": [], + "label": "hideChart", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch", + "type": "Interface", + "tags": [], + "label": "SavedSearch", + "description": [], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.searchSource", + "type": "Object", + "tags": [], + "label": "searchSource", + "description": [], + "signature": [ + "{ create: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; history: Record<string, any>[]; setPreferredSearchStrategyId: (searchStrategyId: string) => void; setField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, value: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "[K]) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; removeField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; setFields: (newFields: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; getId: () => string; getFields: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "; getField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K, recurse?: boolean) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "[K]; getOwnField: <K extends \"type\" | \"query\" | \"source\" | \"sort\" | \"version\" | \"filter\" | \"highlight\" | \"highlightAll\" | \"trackTotalHits\" | \"aggs\" | \"from\" | \"size\" | \"fields\" | \"fieldsFromSource\" | \"index\" | \"searchAfter\" | \"timeout\" | \"terminate_after\" | \"parent\">(field: K) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "[K]; createCopy: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; createChild: (options?: {}) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; setParent: (parent?: Pick<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + ", \"create\" | \"history\" | \"setPreferredSearchStrategyId\" | \"setField\" | \"removeField\" | \"setFields\" | \"getId\" | \"getFields\" | \"getField\" | \"getOwnField\" | \"createCopy\" | \"createChild\" | \"setParent\" | \"getParent\" | \"fetch$\" | \"fetch\" | \"onRequestStart\" | \"getSearchRequestBody\" | \"destroy\" | \"getSerializedFields\" | \"serialize\"> | undefined, options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceOptions", + "text": "SearchSourceOptions" + }, + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + "; getParent: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + " | undefined; fetch$: (options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchOptions", + "text": "ISearchOptions" + }, + ") => ", + "Observable", + "<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.IKibanaSearchResponse", + "text": "IKibanaSearchResponse" + }, + "<", + "SearchResponse", + "<any>>>; fetch: (options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchOptions", + "text": "ISearchOptions" + }, + ") => Promise<", + "SearchResponse", + "<any>>; onRequestStart: (handler: (searchSource: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSource", + "text": "SearchSource" + }, + ", options?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchOptions", + "text": "ISearchOptions" + }, + " | undefined) => Promise<unknown>) => void; getSearchRequestBody: () => any; destroy: () => void; getSerializedFields: (recurse?: boolean) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.SearchSourceFields", + "text": "SearchSourceFields" + }, + "; serialize: () => { searchSourceJSON: string; references: ", + "SavedObjectReference", + "[]; }; }" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.sort", + "type": "Array", + "tags": [], + "label": "sort", + "description": [], + "signature": [ + "[string, string][] | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.columns", + "type": "Array", + "tags": [], + "label": "columns", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.grid", + "type": "Object", + "tags": [], + "label": "grid", + "description": [], + "signature": [ + "{ columns?: Record<string, ", + "DiscoverGridSettingsColumn", + "> | undefined; } | undefined" + ], "path": "src/plugins/discover/public/saved_searches/types.ts", "deprecated": false }, @@ -799,6 +1421,19 @@ ], "path": "src/plugins/discover/public/saved_searches/types.ts", "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.sharingSavedObjectProps", + "type": "Object", + "tags": [], + "label": "sharingSavedObjectProps", + "description": [], + "signature": [ + "{ outcome?: \"conflict\" | \"exactMatch\" | \"aliasMatch\" | undefined; aliasTargetId?: string | undefined; errorJSON?: string | undefined; } | undefined" + ], + "path": "src/plugins/discover/public/saved_searches/types.ts", + "deprecated": false } ], "initialIsOpen": false @@ -807,11 +1442,14 @@ "parentPluginId": "discover", "id": "def-public.SavedSearchLoader", "type": "Interface", - "tags": [], + "tags": [ + "deprecated" + ], "label": "SavedSearchLoader", "description": [], - "path": "src/plugins/discover/public/saved_searches/types.ts", - "deprecated": false, + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", + "deprecated": true, + "references": [], "children": [ { "parentPluginId": "discover", @@ -826,12 +1464,12 @@ "pluginId": "discover", "scope": "public", "docId": "kibDiscoverPluginApi", - "section": "def-public.SavedSearch", - "text": "SavedSearch" + "section": "def-public.LegacySavedSearch", + "text": "LegacySavedSearch" }, ">" ], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false, "children": [ { @@ -844,7 +1482,7 @@ "signature": [ "string" ], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false, "isRequired": true } @@ -861,7 +1499,7 @@ "signature": [ "(id: string) => string" ], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false, "children": [ { @@ -874,7 +1512,7 @@ "signature": [ "string" ], - "path": "src/plugins/discover/public/saved_searches/types.ts", + "path": "src/plugins/discover/public/saved_searches/legacy/types.ts", "deprecated": false, "isRequired": true } @@ -1068,7 +1706,69 @@ "initialIsOpen": false } ], - "objects": [], + "objects": [ + { + "parentPluginId": "discover", + "id": "def-public.__LEGACY", + "type": "Object", + "tags": [ + "deprecated" + ], + "label": "__LEGACY", + "description": [], + "path": "src/plugins/discover/public/saved_searches/index.ts", + "deprecated": true, + "references": [ + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts" + }, + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts" + } + ], + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.__LEGACY.createSavedSearchesLoader", + "type": "Function", + "tags": [], + "label": "createSavedSearchesLoader", + "description": [], + "signature": [ + "({ savedObjectsClient, savedObjects }: Services) => ", + { + "pluginId": "savedObjects", + "scope": "public", + "docId": "kibSavedObjectsPluginApi", + "section": "def-public.SavedObjectLoader", + "text": "SavedObjectLoader" + } + ], + "path": "src/plugins/discover/public/saved_searches/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.__LEGACY.createSavedSearchesLoader.$1", + "type": "Object", + "tags": [], + "label": "__0", + "description": [], + "signature": [ + "Services" + ], + "path": "src/plugins/discover/public/saved_searches/legacy/saved_searches.ts", + "deprecated": false + } + ] + } + ], + "initialIsOpen": false + } + ], "setup": { "parentPluginId": "discover", "id": "def-public.DiscoverSetup", @@ -1134,19 +1834,21 @@ "children": [ { "parentPluginId": "discover", - "id": "def-public.DiscoverStart.savedSearchLoader", + "id": "def-public.DiscoverStart.__LEGACY", "type": "Object", "tags": [], - "label": "savedSearchLoader", + "label": "__LEGACY", "description": [], "signature": [ + "{ savedSearchLoader: ", { "pluginId": "savedObjects", "scope": "public", "docId": "kibSavedObjectsPluginApi", "section": "def-public.SavedObjectLoader", "text": "SavedObjectLoader" - } + }, + "; }" ], "path": "src/plugins/discover/public/plugin.tsx", "deprecated": false diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index aee0f4b9724c6..46e681aabc0a6 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -18,7 +18,7 @@ Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-disco | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 82 | 0 | 56 | 6 | +| 103 | 0 | 77 | 7 | ## Client @@ -28,6 +28,9 @@ Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-disco ### Start <DocDefinitionList data={[discoverObj.client.start]}/> +### Objects +<DocDefinitionList data={discoverObj.client.objects}/> + ### Functions <DocDefinitionList data={discoverObj.client.functions}/> diff --git a/api_docs/elastic_apm_generator.json b/api_docs/elastic_apm_generator.json index dc69c08bba5b2..24f11791d92b6 100644 --- a/api_docs/elastic_apm_generator.json +++ b/api_docs/elastic_apm_generator.json @@ -11,6 +11,37 @@ "server": { "classes": [], "functions": [ + { + "parentPluginId": "@elastic/apm-generator", + "id": "def-server.getBreakdownMetrics", + "type": "Function", + "tags": [], + "label": "getBreakdownMetrics", + "description": [], + "signature": [ + "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]) => Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" + ], + "path": "packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-generator", + "id": "def-server.getBreakdownMetrics.$1", + "type": "Array", + "tags": [], + "label": "events", + "description": [], + "signature": [ + "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" + ], + "path": "packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@elastic/apm-generator", "id": "def-server.getObserverDefaults", @@ -19,7 +50,7 @@ "label": "getObserverDefaults", "description": [], "signature": [ - "() => Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>" + "() => Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>" ], "path": "packages/elastic-apm-generator/src/lib/defaults/get_observer_defaults.ts", "deprecated": false, @@ -35,7 +66,7 @@ "label": "getSpanDestinationMetrics", "description": [], "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[]) => Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[]" + "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]) => { \"metricset.name\": string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'host.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.duration.histogram'?: { values: number[]; counts: number[]; } | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; }[]" ], "path": "packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts", "deprecated": false, @@ -48,7 +79,7 @@ "label": "events", "description": [], "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[]" + "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" ], "path": "packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts", "deprecated": false, @@ -66,7 +97,7 @@ "label": "getTransactionMetrics", "description": [], "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[]) => { \"transaction.duration.histogram\": { values: number[]; counts: number[]; }; _doc_count: number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'metricset.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.destination.service.response_time.sum.us'?: number | undefined; 'span.destination.service.response_time.count'?: number | undefined; }[]" + "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]) => { 'transaction.duration.histogram': { values: number[]; counts: number[]; }; _doc_count: number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'host.name'?: string | undefined; 'metricset.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.destination.service.response_time.sum.us'?: number | undefined; 'span.destination.service.response_time.count'?: number | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; }[]" ], "path": "packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts", "deprecated": false, @@ -79,7 +110,7 @@ "label": "events", "description": [], "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[]" + "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" ], "path": "packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts", "deprecated": false, @@ -203,7 +234,7 @@ "label": "toElasticsearchOutput", "description": [], "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[], versionOverride: string | undefined) => { _index: string; _source: {}; }[]" + "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[], versionOverride: string | undefined) => { _index: string; _source: {}; }[]" ], "path": "packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts", "deprecated": false, @@ -216,7 +247,7 @@ "label": "events", "description": [], "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; }>[]" + "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" ], "path": "packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts", "deprecated": false, diff --git a/api_docs/elastic_apm_generator.mdx b/api_docs/elastic_apm_generator.mdx index 3b7667a6837b5..4c95050b09c28 100644 --- a/api_docs/elastic_apm_generator.mdx +++ b/api_docs/elastic_apm_generator.mdx @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 15 | 0 | 15 | 2 | +| 17 | 0 | 17 | 2 | ## Server diff --git a/api_docs/es_ui_shared.json b/api_docs/es_ui_shared.json index 83d71b321cfcf..da0ba7b688c93 100644 --- a/api_docs/es_ui_shared.json +++ b/api_docs/es_ui_shared.json @@ -1175,7 +1175,7 @@ "label": "method", "description": [], "signature": [ - "\"get\" | \"post\" | \"put\" | \"delete\" | \"patch\" | \"head\"" + "\"delete\" | \"get\" | \"post\" | \"put\" | \"patch\" | \"head\"" ], "path": "src/plugins/es_ui_shared/public/request/send_request.ts", "deprecated": false diff --git a/api_docs/event_log.json b/api_docs/event_log.json index 1991fbff2589d..60a3d9e83be7b 100644 --- a/api_docs/event_log.json +++ b/api_docs/event_log.json @@ -753,7 +753,7 @@ "label": "logEvent", "description": [], "signature": [ - "(properties: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => void" + "(properties: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => void" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, @@ -766,7 +766,7 @@ "label": "properties", "description": [], "signature": [ - "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" + "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, @@ -783,7 +783,7 @@ "label": "startTiming", "description": [], "signature": [ - "(event: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => void" + "(event: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => void" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, @@ -796,7 +796,7 @@ "label": "event", "description": [], "signature": [ - "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" + "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, @@ -813,7 +813,7 @@ "label": "stopTiming", "description": [], "signature": [ - "(event: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => void" + "(event: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => void" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, @@ -826,7 +826,7 @@ "label": "event", "description": [], "signature": [ - "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" + "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, @@ -886,7 +886,7 @@ "label": "data", "description": [], "signature": [ - "(Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}> | undefined)[]" + "(Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}> | undefined)[]" ], "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", "deprecated": false @@ -905,7 +905,7 @@ "label": "IEvent", "description": [], "signature": [ - "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" + "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/generated/schemas.ts", "deprecated": false, @@ -919,7 +919,7 @@ "label": "IValidatedEvent", "description": [], "signature": [ - "Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}> | undefined" + "Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}> | undefined" ], "path": "x-pack/plugins/event_log/generated/schemas.ts", "deprecated": false, @@ -1138,7 +1138,7 @@ "label": "getLogger", "description": [], "signature": [ - "(properties: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => ", + "(properties: DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined) => ", { "pluginId": "eventLog", "scope": "server", @@ -1158,7 +1158,7 @@ "label": "properties", "description": [], "signature": [ - "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; outcome?: string | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" + "DeepPartial<DeepWriteable<Readonly<{ tags?: string[] | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ total_indexing_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; } & {}> | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; rel?: string | undefined; namespace?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ scheduled?: string | undefined; schedule_delay?: number | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; message?: string | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; category?: string[] | undefined; outcome?: string | undefined; url?: string | undefined; code?: string | undefined; original?: string | undefined; action?: string | undefined; kind?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; duration?: number | undefined; hash?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/server/types.ts", "deprecated": false, diff --git a/api_docs/expressions.json b/api_docs/expressions.json index 5cb989ee85e61..952184350bc79 100644 --- a/api_docs/expressions.json +++ b/api_docs/expressions.json @@ -2494,7 +2494,7 @@ "label": "types", "description": [], "signature": [ - "(string[] & (\"date\" | \"filter\" | ", + "(string[] & (\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -2502,7 +2502,7 @@ "section": "def-common.KnownTypeToString", "text": "KnownTypeToString" }, - "<T>)[]) | (string[] & (\"date\" | \"filter\" | ArrayTypeToArgumentString<T>)[]) | (string[] & (\"date\" | \"filter\" | UnresolvedTypeToArgumentString<T>)[]) | (string[] & (\"date\" | \"filter\" | UnresolvedArrayTypeToArgumentString<T>)[]) | undefined" + "<T>)[]) | (string[] & (\"filter\" | \"date\" | ArrayTypeToArgumentString<T>)[]) | (string[] & (\"filter\" | \"date\" | UnresolvedTypeToArgumentString<T>)[]) | (string[] & (\"filter\" | \"date\" | UnresolvedArrayTypeToArgumentString<T>)[]) | undefined" ], "path": "src/plugins/expressions/common/expression_functions/expression_function_parameter.ts", "deprecated": false @@ -7683,7 +7683,7 @@ "\nName of type of value this function outputs." ], "signature": [ - "\"date\" | \"filter\" | ", + "\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -10477,57 +10477,6 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "expressions", - "id": "def-public.SerializedFieldFormat", - "type": "Interface", - "tags": [], - "label": "SerializedFieldFormat", - "description": [ - "\nJSON representation of a field formatter configuration.\nIs used to carry information about how to format data in\na data table as part of the column definition." - ], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.SerializedFieldFormat", - "text": "SerializedFieldFormat" - }, - "<TParams>" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressions", - "id": "def-public.SerializedFieldFormat.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false - }, - { - "parentPluginId": "expressions", - "id": "def-public.SerializedFieldFormat.params", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "TParams | undefined" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false - } - ], - "initialIsOpen": false } ], "enums": [ @@ -10692,7 +10641,7 @@ "\nThis type represents the `type` of any `DatatableColumn` in a `Datatable`.\nits duplicated from KBN_FIELD_TYPES" ], "signature": [ - "\"string\" | \"number\" | \"boolean\" | \"object\" | \"date\" | \"_source\" | \"attachment\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" + "\"string\" | \"number\" | \"boolean\" | \"object\" | \"_source\" | \"attachment\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" ], "path": "src/plugins/expressions/common/expression_types/specs/datatable.ts", "deprecated": false, @@ -11558,7 +11507,7 @@ "\nThis can convert a type into a known Expression string representation of\nthat type. For example, `TypeToString<Datatable>` will resolve to `'datatable'`.\nThis allows Expression Functions to continue to specify their type in a\nsimple string format." ], "signature": [ - "\"date\" | \"filter\" | ", + "\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -11582,7 +11531,7 @@ "\nTypes used in Expressions that don't map to a primitive cleanly:\n\n`date` is typed as a number or string, and represents a date" ], "signature": [ - "\"date\" | \"filter\"" + "\"filter\" | \"date\"" ], "path": "src/plugins/expressions/common/types/common.ts", "deprecated": false, @@ -14170,7 +14119,7 @@ "label": "types", "description": [], "signature": [ - "(string[] & (\"date\" | \"filter\" | ", + "(string[] & (\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -14178,7 +14127,7 @@ "section": "def-common.KnownTypeToString", "text": "KnownTypeToString" }, - "<T>)[]) | (string[] & (\"date\" | \"filter\" | ArrayTypeToArgumentString<T>)[]) | (string[] & (\"date\" | \"filter\" | UnresolvedTypeToArgumentString<T>)[]) | (string[] & (\"date\" | \"filter\" | UnresolvedArrayTypeToArgumentString<T>)[]) | undefined" + "<T>)[]) | (string[] & (\"filter\" | \"date\" | ArrayTypeToArgumentString<T>)[]) | (string[] & (\"filter\" | \"date\" | UnresolvedTypeToArgumentString<T>)[]) | (string[] & (\"filter\" | \"date\" | UnresolvedArrayTypeToArgumentString<T>)[]) | undefined" ], "path": "src/plugins/expressions/common/expression_functions/expression_function_parameter.ts", "deprecated": false @@ -17730,7 +17679,7 @@ "\nName of type of value this function outputs." ], "signature": [ - "\"date\" | \"filter\" | ", + "\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -19489,57 +19438,6 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "expressions", - "id": "def-server.SerializedFieldFormat", - "type": "Interface", - "tags": [], - "label": "SerializedFieldFormat", - "description": [ - "\nJSON representation of a field formatter configuration.\nIs used to carry information about how to format data in\na data table as part of the column definition." - ], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.SerializedFieldFormat", - "text": "SerializedFieldFormat" - }, - "<TParams>" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressions", - "id": "def-server.SerializedFieldFormat.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false - }, - { - "parentPluginId": "expressions", - "id": "def-server.SerializedFieldFormat.params", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "TParams | undefined" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false - } - ], - "initialIsOpen": false } ], "enums": [ @@ -19704,7 +19602,7 @@ "\nThis type represents the `type` of any `DatatableColumn` in a `Datatable`.\nits duplicated from KBN_FIELD_TYPES" ], "signature": [ - "\"string\" | \"number\" | \"boolean\" | \"object\" | \"date\" | \"_source\" | \"attachment\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" + "\"string\" | \"number\" | \"boolean\" | \"object\" | \"_source\" | \"attachment\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" ], "path": "src/plugins/expressions/common/expression_types/specs/datatable.ts", "deprecated": false, @@ -20468,7 +20366,7 @@ "\nThis can convert a type into a known Expression string representation of\nthat type. For example, `TypeToString<Datatable>` will resolve to `'datatable'`.\nThis allows Expression Functions to continue to specify their type in a\nsimple string format." ], "signature": [ - "\"date\" | \"filter\" | ", + "\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -20492,7 +20390,7 @@ "\nTypes used in Expressions that don't map to a primitive cleanly:\n\n`date` is typed as a number or string, and represents a date" ], "signature": [ - "\"date\" | \"filter\"" + "\"filter\" | \"date\"" ], "path": "src/plugins/expressions/common/types/common.ts", "deprecated": false, @@ -23037,7 +22935,7 @@ "label": "types", "description": [], "signature": [ - "(string[] & (\"date\" | \"filter\" | ", + "(string[] & (\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -23045,7 +22943,7 @@ "section": "def-common.KnownTypeToString", "text": "KnownTypeToString" }, - "<T>)[]) | (string[] & (\"date\" | \"filter\" | ArrayTypeToArgumentString<T>)[]) | (string[] & (\"date\" | \"filter\" | UnresolvedTypeToArgumentString<T>)[]) | (string[] & (\"date\" | \"filter\" | UnresolvedArrayTypeToArgumentString<T>)[]) | undefined" + "<T>)[]) | (string[] & (\"filter\" | \"date\" | ArrayTypeToArgumentString<T>)[]) | (string[] & (\"filter\" | \"date\" | UnresolvedTypeToArgumentString<T>)[]) | (string[] & (\"filter\" | \"date\" | UnresolvedArrayTypeToArgumentString<T>)[]) | undefined" ], "path": "src/plugins/expressions/common/expression_functions/expression_function_parameter.ts", "deprecated": false @@ -27529,7 +27427,7 @@ "label": "type", "description": [], "signature": [ - "\"string\" | \"number\" | \"boolean\" | \"object\" | \"date\" | \"_source\" | \"attachment\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" + "\"string\" | \"number\" | \"boolean\" | \"object\" | \"_source\" | \"attachment\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" ], "path": "src/plugins/expressions/common/expression_types/specs/datatable.ts", "deprecated": false @@ -27590,13 +27488,21 @@ ], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined" ], "path": "src/plugins/expressions/common/expression_types/specs/datatable.ts", "deprecated": false @@ -29657,7 +29563,7 @@ "\nName of type of value this function outputs." ], "signature": [ - "\"date\" | \"filter\" | ", + "\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -32751,57 +32657,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "expressions", - "id": "def-common.SerializedFieldFormat", - "type": "Interface", - "tags": [], - "label": "SerializedFieldFormat", - "description": [ - "\nJSON representation of a field formatter configuration.\nIs used to carry information about how to format data in\na data table as part of the column definition." - ], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.SerializedFieldFormat", - "text": "SerializedFieldFormat" - }, - "<TParams>" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressions", - "id": "def-common.SerializedFieldFormat.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false - }, - { - "parentPluginId": "expressions", - "id": "def-common.SerializedFieldFormat.params", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "TParams | undefined" - ], - "path": "src/plugins/expressions/common/types/common.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "expressions", "id": "def-common.UiSettingArguments", @@ -33048,7 +32903,7 @@ "\nThis type represents the `type` of any `DatatableColumn` in a `Datatable`.\nits duplicated from KBN_FIELD_TYPES" ], "signature": [ - "\"string\" | \"number\" | \"boolean\" | \"object\" | \"date\" | \"_source\" | \"attachment\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" + "\"string\" | \"number\" | \"boolean\" | \"object\" | \"_source\" | \"attachment\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"murmur3\" | \"unknown\" | \"conflict\" | \"nested\" | \"histogram\" | \"null\"" ], "path": "src/plugins/expressions/common/expression_types/specs/datatable.ts", "deprecated": false, @@ -34684,7 +34539,7 @@ "\nThis can convert a type into a known Expression string representation of\nthat type. For example, `TypeToString<Datatable>` will resolve to `'datatable'`.\nThis allows Expression Functions to continue to specify their type in a\nsimple string format." ], "signature": [ - "\"date\" | \"filter\" | ", + "\"filter\" | \"date\" | ", { "pluginId": "expressions", "scope": "common", @@ -34722,7 +34577,7 @@ "\nTypes used in Expressions that don't map to a primitive cleanly:\n\n`date` is typed as a number or string, and represents a date" ], "signature": [ - "\"date\" | \"filter\"" + "\"filter\" | \"date\"" ], "path": "src/plugins/expressions/common/types/common.ts", "deprecated": false, diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 82b35631ddfe1..9f086cc496faf 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2095 | 27 | 1646 | 4 | +| 2086 | 27 | 1640 | 4 | ## Client diff --git a/api_docs/fleet.json b/api_docs/fleet.json index 0bdb078d6f70d..b50a2f598b926 100644 --- a/api_docs/fleet.json +++ b/api_docs/fleet.json @@ -2624,7 +2624,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, id: string, withPackagePolicies?: boolean) => Promise<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, id: string, withPackagePolicies?: boolean) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -2646,25 +2646,7 @@ "label": "soClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -2722,7 +2704,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -2786,6 +2776,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -3013,7 +3013,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, options: Readonly<{ page?: number | undefined; perPage?: number | undefined; sortField?: string | undefined; sortOrder?: \"asc\" | \"desc\" | undefined; kuery?: any; showUpgradeable?: boolean | undefined; } & {}> & { withPackagePolicies?: boolean | undefined; }) => Promise<{ items: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, options: Readonly<{ page?: number | undefined; perPage?: number | undefined; sortField?: string | undefined; sortOrder?: \"asc\" | \"desc\" | undefined; kuery?: any; showUpgradeable?: boolean | undefined; } & {}> & { withPackagePolicies?: boolean | undefined; }) => Promise<{ items: ", { "pluginId": "fleet", "scope": "common", @@ -3035,25 +3035,7 @@ "label": "soClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -3111,7 +3093,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -3175,6 +3165,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -3395,7 +3395,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Promise<string>" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Promise<string>" ], "path": "x-pack/plugins/fleet/server/services/index.ts", "deprecated": false, @@ -3409,25 +3409,7 @@ "label": "soClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -3485,7 +3467,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -3549,6 +3539,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -3756,7 +3756,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, id: string, options?: { standalone: boolean; } | undefined) => Promise<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, id: string, options?: { standalone: boolean; } | undefined) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -3778,25 +3778,7 @@ "label": "soClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -3854,7 +3836,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -3918,6 +3908,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -4148,7 +4148,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, ids: string[], options?: { fields?: string[] | undefined; }) => Promise<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, ids: string[], options?: { fields?: string[] | undefined; }) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -4170,25 +4170,7 @@ "label": "soClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -4246,7 +4228,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -4310,6 +4300,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -4584,7 +4584,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -4876,7 +4876,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -5231,7 +5231,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, pkgName: string, datasetPath: string) => Promise<string | undefined>" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, pkgName: string, datasetPath: string) => Promise<string | undefined>" ], "path": "x-pack/plugins/fleet/server/services/index.ts", "deprecated": false, @@ -5252,7 +5252,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "x-pack/plugins/fleet/server/services/index.ts", "deprecated": false, @@ -5451,7 +5451,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; pkgName: string; }) => Promise<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; pkgName: string; }) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -5481,7 +5481,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; pkgName: string; }" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; pkgName: string; }" ], "path": "x-pack/plugins/fleet/server/services/epm/packages/get.ts", "deprecated": false @@ -6579,7 +6579,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installed\"; savedObject: ", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installed\"; savedObject: ", "SavedObject", "<", { @@ -6597,7 +6597,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installing\"; savedObject: ", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installing\"; savedObject: ", "SavedObject", "<", { @@ -6615,7 +6615,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"not_installed\"; } & { integration?: string | undefined; id: string; }) | (Pick<", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"not_installed\"; } & { integration?: string | undefined; id: string; }) | (Pick<", { "pluginId": "fleet", "scope": "common", @@ -6623,7 +6623,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"install_failed\"; } & { integration?: string | undefined; id: string; })) => boolean" + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"install_failed\"; } & { integration?: string | undefined; id: string; })) => boolean" ], "path": "x-pack/plugins/fleet/common/services/packages_with_integrations.ts", "deprecated": false, @@ -6835,7 +6835,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installed\"; savedObject: ", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installed\"; savedObject: ", "SavedObject", "<", { @@ -6853,7 +6853,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installing\"; savedObject: ", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installing\"; savedObject: ", "SavedObject", "<", { @@ -6871,7 +6871,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"not_installed\"; } & { integration?: string | undefined; id: string; }) | (Pick<", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"not_installed\"; } & { integration?: string | undefined; id: string; }) | (Pick<", { "pluginId": "fleet", "scope": "common", @@ -6879,7 +6879,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"install_failed\"; } & { integration?: string | undefined; id: string; })" + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"install_failed\"; } & { integration?: string | undefined; id: string; })" ], "path": "x-pack/plugins/fleet/common/services/packages_with_integrations.ts", "deprecated": false, @@ -7854,7 +7854,7 @@ "label": "status", "description": [], "signature": [ - "\"warning\" | \"offline\" | \"online\" | \"error\" | \"inactive\" | \"enrolling\" | \"unenrolling\" | \"updating\" | \"degraded\" | undefined" + "\"offline\" | \"online\" | \"error\" | \"warning\" | \"inactive\" | \"enrolling\" | \"unenrolling\" | \"updating\" | \"degraded\" | undefined" ], "path": "x-pack/plugins/fleet/common/types/models/agent.ts", "deprecated": false @@ -11241,7 +11241,7 @@ "label": "missing_requirements", "description": [], "signature": [ - "(\"fleet_server\" | \"tls_required\" | \"api_keys\" | \"fleet_admin_user\" | \"encrypted_saved_object_encryption_key_required\")[]" + "(\"fleet_server\" | \"security_required\" | \"tls_required\" | \"api_keys\" | \"fleet_admin_user\" | \"encrypted_saved_object_encryption_key_required\")[]" ], "path": "x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts", "deprecated": false @@ -12795,6 +12795,19 @@ "description": [], "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.IntegrationCardItem.categories", + "type": "Array", + "tags": [], + "label": "categories", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/fleet/common/types/models/epm.ts", + "deprecated": false } ], "initialIsOpen": false @@ -13668,7 +13681,7 @@ "section": "def-common.NewPackagePolicy", "text": "NewPackagePolicy" }, - ", \"enabled\" | \"description\" | \"name\" | \"package\" | \"policy_id\" | \"namespace\" | \"output_id\" | \"vars\">" + ", \"description\" | \"name\" | \"enabled\" | \"package\" | \"policy_id\" | \"namespace\" | \"output_id\" | \"vars\">" ], "path": "x-pack/plugins/fleet/common/types/models/package_policy.ts", "deprecated": false, @@ -14857,7 +14870,7 @@ "section": "def-common.NewPackagePolicy", "text": "NewPackagePolicy" }, - ", \"enabled\" | \"description\" | \"name\" | \"policy_id\" | \"namespace\" | \"output_id\" | \"vars\">> & { name: string; package: Partial<", + ", \"description\" | \"name\" | \"enabled\" | \"policy_id\" | \"namespace\" | \"output_id\" | \"vars\">> & { name: string; package: Partial<", { "pluginId": "fleet", "scope": "common", @@ -17011,7 +17024,7 @@ "label": "AgentStatus", "description": [], "signature": [ - "\"warning\" | \"offline\" | \"online\" | \"error\" | \"inactive\" | \"enrolling\" | \"unenrolling\" | \"updating\" | \"degraded\"" + "\"offline\" | \"online\" | \"error\" | \"warning\" | \"inactive\" | \"enrolling\" | \"unenrolling\" | \"updating\" | \"degraded\"" ], "path": "x-pack/plugins/fleet/common/types/models/agent.ts", "deprecated": false, @@ -17662,6 +17675,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.FLEET_APM_PACKAGE", + "type": "string", + "tags": [], + "label": "FLEET_APM_PACKAGE", + "description": [], + "signature": [ + "\"apm\"" + ], + "path": "x-pack/plugins/fleet/common/constants/epm.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.FLEET_ELASTIC_AGENT_PACKAGE", @@ -17760,6 +17787,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.FLEET_SYNTHETICS_PACKAGE", + "type": "string", + "tags": [], + "label": "FLEET_SYNTHETICS_PACKAGE", + "description": [], + "signature": [ + "\"synthetics\"" + ], + "path": "x-pack/plugins/fleet/common/constants/epm.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.FLEET_SYSTEM_PACKAGE", @@ -18639,7 +18680,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installed\"; savedObject: ", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installed\"; savedObject: ", "SavedObject", "<", { @@ -18657,7 +18698,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installing\"; savedObject: ", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"installing\"; savedObject: ", "SavedObject", "<", { @@ -18675,7 +18716,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"not_installed\"; } & { integration?: string | undefined; id: string; }) | (Pick<", + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"not_installed\"; } & { integration?: string | undefined; id: string; }) | (Pick<", { "pluginId": "fleet", "scope": "common", @@ -18683,7 +18724,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"install_failed\"; } & { integration?: string | undefined; id: string; })" + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\"> & { status: \"install_failed\"; } & { integration?: string | undefined; id: string; })" ], "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false, @@ -18748,7 +18789,7 @@ "label": "PackagePolicySOAttributes", "description": [], "signature": [ - "{ enabled: boolean; description?: string | undefined; name: string; package?: ", + "{ description?: string | undefined; name: string; enabled: boolean; package?: ", { "pluginId": "fleet", "scope": "common", @@ -19074,7 +19115,7 @@ "section": "def-common.RegistryImage", "text": "RegistryImage" }, - "[]) | undefined; name: string; version: string; path: string; download: string; internal?: boolean | undefined; data_streams?: ", + "[]) | undefined; categories?: (\"custom\" | \"aws\" | \"azure\" | \"cloud\" | \"config_management\" | \"containers\" | \"crm\" | \"datastore\" | \"elastic_stack\" | \"google_cloud\" | \"kubernetes\" | \"languages\" | \"message_queue\" | \"monitoring\" | \"network\" | \"notification\" | \"os_system\" | \"productivity\" | \"security\" | \"support\" | \"ticketing\" | \"version_control\" | \"web\" | undefined)[] | undefined; name: string; version: string; path: string; download: string; internal?: boolean | undefined; data_streams?: ", { "pluginId": "fleet", "scope": "common", @@ -19112,7 +19153,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"type\" | \"title\" | \"description\" | \"icons\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\">[]" + ", \"type\" | \"title\" | \"description\" | \"icons\" | \"categories\" | \"name\" | \"version\" | \"path\" | \"download\" | \"internal\" | \"data_streams\" | \"release\" | \"policy_templates\">[]" ], "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false, diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 88d006982d0f0..3d01ccbb559a1 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -18,7 +18,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1207 | 15 | 1107 | 10 | +| 1210 | 15 | 1110 | 10 | ## Client diff --git a/api_docs/global_search.json b/api_docs/global_search.json index a8b5ca35c634e..7dd6198974f6c 100644 --- a/api_docs/global_search.json +++ b/api_docs/global_search.json @@ -625,7 +625,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; typeRegistry: Pick<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; typeRegistry: Pick<", { "pluginId": "core", "scope": "server", diff --git a/api_docs/home.json b/api_docs/home.json index 585bd6b18d07b..1bda24024cf7c 100644 --- a/api_docs/home.json +++ b/api_docs/home.json @@ -959,7 +959,7 @@ "label": "InstructionsSchema", "description": [], "signature": [ - "{ readonly params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; readonly instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }" + "{ readonly params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; readonly instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -981,7 +981,7 @@ "section": "def-server.Writable", "text": "Writable" }, - "<Readonly<{ status?: string | undefined; darkPreviewImagePath?: string | undefined; iconPath?: string | undefined; statusMsg?: string | undefined; } & { id: string; description: string; name: string; savedObjects: Readonly<{ version?: any; attributes?: any; } & { type: string; id: string; references: any[]; }>[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]; dataIndices: Readonly<{} & { id: string; fields: Record<string, any>; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", + "<Readonly<{ status?: string | undefined; darkPreviewImagePath?: string | undefined; iconPath?: string | undefined; statusMsg?: string | undefined; } & { id: string; description: string; name: string; defaultIndex: string; savedObjects: Readonly<{ version?: any; attributes?: any; } & { type: string; id: string; references: any[]; }>[]; previewImagePath: string; overviewDashboard: string; appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]; dataIndices: Readonly<{} & { id: string; fields: Record<string, any>; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", "SavedObject", "<unknown>[]) => void; addAppLinksToSampleDataset: (id: string, appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]) => void; replacePanelInSampleDatasetDashboard: ({ sampleDataId, dashboardId, oldEmbeddableId, embeddableId, embeddableType, embeddableConfig, }: ", "SampleDatasetDashboardPanel", @@ -1007,7 +1007,7 @@ "section": "def-server.Writable", "text": "Writable" }, - "<Readonly<{ status?: string | undefined; darkPreviewImagePath?: string | undefined; iconPath?: string | undefined; statusMsg?: string | undefined; } & { id: string; description: string; name: string; savedObjects: Readonly<{ version?: any; attributes?: any; } & { type: string; id: string; references: any[]; }>[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]; dataIndices: Readonly<{} & { id: string; fields: Record<string, any>; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>" + "<Readonly<{ status?: string | undefined; darkPreviewImagePath?: string | undefined; iconPath?: string | undefined; statusMsg?: string | undefined; } & { id: string; description: string; name: string; defaultIndex: string; savedObjects: Readonly<{ version?: any; attributes?: any; } & { type: string; id: string; references: any[]; }>[]; previewImagePath: string; overviewDashboard: string; appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]; dataIndices: Readonly<{} & { id: string; fields: Record<string, any>; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>" ], "path": "src/plugins/home/server/services/sample_data/lib/sample_dataset_registry_types.ts", "deprecated": false, @@ -1025,7 +1025,7 @@ "signature": [ "(context: ", "TutorialContext", - ") => Readonly<{ isBeta?: boolean | undefined; savedObjects?: any[] | undefined; euiIconType?: string | undefined; previewImagePath?: string | undefined; moduleName?: string | undefined; completionTimeMinutes?: number | undefined; elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; savedObjectsInstallMsg?: string | undefined; customStatusCheckName?: string | undefined; integrationBrowserCategories?: string[] | undefined; eprPackageOverlap?: string | undefined; } & { id: string; name: string; category: \"security\" | \"metrics\" | \"other\" | \"logging\"; shortDescription: string; longDescription: string; onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }>" + ") => Readonly<{ isBeta?: boolean | undefined; savedObjects?: any[] | undefined; euiIconType?: string | undefined; previewImagePath?: string | undefined; moduleName?: string | undefined; completionTimeMinutes?: number | undefined; elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; savedObjectsInstallMsg?: string | undefined; customStatusCheckName?: string | undefined; integrationBrowserCategories?: string[] | undefined; eprPackageOverlap?: string | undefined; } & { id: string; name: string; category: \"other\" | \"security\" | \"metrics\" | \"logging\"; shortDescription: string; longDescription: string; onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }>" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts", "deprecated": false, @@ -1055,7 +1055,7 @@ "label": "TutorialSchema", "description": [], "signature": [ - "{ readonly isBeta?: boolean | undefined; readonly savedObjects?: any[] | undefined; readonly euiIconType?: string | undefined; readonly previewImagePath?: string | undefined; readonly moduleName?: string | undefined; readonly completionTimeMinutes?: number | undefined; readonly elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; readonly savedObjectsInstallMsg?: string | undefined; readonly customStatusCheckName?: string | undefined; readonly integrationBrowserCategories?: string[] | undefined; readonly eprPackageOverlap?: string | undefined; readonly id: string; readonly name: string; readonly category: \"security\" | \"metrics\" | \"other\" | \"logging\"; readonly shortDescription: string; readonly longDescription: string; readonly onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }" + "{ readonly isBeta?: boolean | undefined; readonly savedObjects?: any[] | undefined; readonly euiIconType?: string | undefined; readonly previewImagePath?: string | undefined; readonly moduleName?: string | undefined; readonly completionTimeMinutes?: number | undefined; readonly elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; readonly savedObjectsInstallMsg?: string | undefined; readonly customStatusCheckName?: string | undefined; readonly integrationBrowserCategories?: string[] | undefined; readonly eprPackageOverlap?: string | undefined; readonly id: string; readonly name: string; readonly category: \"other\" | \"security\" | \"metrics\" | \"logging\"; readonly shortDescription: string; readonly longDescription: string; readonly onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ iconType?: string | undefined; message?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; text?: string | undefined; error?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record<string, any>; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{} & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -1314,7 +1314,7 @@ "section": "def-server.Writable", "text": "Writable" }, - "<Readonly<{ status?: string | undefined; darkPreviewImagePath?: string | undefined; iconPath?: string | undefined; statusMsg?: string | undefined; } & { id: string; description: string; name: string; savedObjects: Readonly<{ version?: any; attributes?: any; } & { type: string; id: string; references: any[]; }>[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]; dataIndices: Readonly<{} & { id: string; fields: Record<string, any>; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", + "<Readonly<{ status?: string | undefined; darkPreviewImagePath?: string | undefined; iconPath?: string | undefined; statusMsg?: string | undefined; } & { id: string; description: string; name: string; defaultIndex: string; savedObjects: Readonly<{ version?: any; attributes?: any; } & { type: string; id: string; references: any[]; }>[]; previewImagePath: string; overviewDashboard: string; appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]; dataIndices: Readonly<{} & { id: string; fields: Record<string, any>; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", "SavedObject", "<unknown>[]) => void; addAppLinksToSampleDataset: (id: string, appLinks: Readonly<{} & { label: string; path: string; icon: string; }>[]) => void; replacePanelInSampleDatasetDashboard: ({ sampleDataId, dashboardId, oldEmbeddableId, embeddableId, embeddableType, embeddableConfig, }: ", "SampleDatasetDashboardPanel", diff --git a/api_docs/kbn_dev_utils.json b/api_docs/kbn_dev_utils.json index 04ce7aebc51e6..1fea3bfd21ae8 100644 --- a/api_docs/kbn_dev_utils.json +++ b/api_docs/kbn_dev_utils.json @@ -26,7 +26,9 @@ "type": "Function", "tags": [], "label": "fromEnv", - "description": [], + "description": [ + "\nCreate a CiStatsReporter by inspecting the ENV for the necessary config" + ], "signature": [ "(log: ", { @@ -92,7 +94,13 @@ "label": "config", "description": [], "signature": [ - "Config", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Config", + "text": "Config" + }, " | undefined" ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", @@ -128,7 +136,9 @@ "type": "Function", "tags": [], "label": "isEnabled", - "description": [], + "description": [ + "\nDetermine if CI_STATS is explicitly disabled by the environment. To determine\nif the CiStatsReporter has enough information in the environment to send metrics\nfor builds use #hasBuildConfig()." + ], "signature": [ "() => boolean" ], @@ -143,7 +153,9 @@ "type": "Function", "tags": [], "label": "hasBuildConfig", - "description": [], + "description": [ + "\nDetermines if the CiStatsReporter is disabled by the environment, or properly\nconfigured and able to send stats" + ], "signature": [ "() => boolean" ], @@ -216,7 +228,15 @@ "section": "def-server.CiStatsMetric", "text": "CiStatsMetric" }, - "[]) => Promise<true | undefined>" + "[], options?: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.MetricsOptions", + "text": "MetricsOptions" + }, + " | undefined) => Promise<true | undefined>" ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false, @@ -241,6 +261,27 @@ "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.CiStatsReporter.metrics.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.MetricsOptions", + "text": "MetricsOptions" + }, + " | undefined" + ], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": false } ], "returnComment": [] @@ -644,19 +685,59 @@ "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", "deprecated": false, "isRequired": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLog.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.ToolingLogOptions", + "text": "ToolingLogOptions" + }, + " | undefined" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false, + "isRequired": false } ], "returnComment": [] }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLog.getIndent", + "type": "Function", + "tags": [], + "label": "getIndent", + "description": [ + "\nGet the current indentation level of the ToolingLog" + ], + "signature": [ + "() => number" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.ToolingLog.indent", "type": "Function", "tags": [], "label": "indent", - "description": [], + "description": [ + "\nIndent the output of the ToolingLog by some character (4 is a good choice usually).\n\nIf provided, the `block` function will be executed and once it's promise is resolved\nor rejected the indentation will be reset to its original state.\n" + ], "signature": [ - "(delta?: number) => number" + "<T>(delta?: number, block?: (() => Promise<T>) | undefined) => Promise<T> | undefined" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", "deprecated": false, @@ -667,13 +748,31 @@ "type": "number", "tags": [], "label": "delta", - "description": [], + "description": [ + "the number of spaces to increase/decrease the indentation" + ], "signature": [ "number" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", "deprecated": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLog.indent.$2", + "type": "Function", + "tags": [], + "label": "block", + "description": [ + "a function to run and reset any indentation changes after" + ], + "signature": [ + "(() => Promise<T>) | undefined" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false, + "isRequired": false } ], "returnComment": [] @@ -897,7 +996,13 @@ "description": [], "signature": [ "() => ", - "Writer", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Writer", + "text": "Writer" + }, "[]" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", @@ -914,7 +1019,13 @@ "description": [], "signature": [ "(writers: ", - "Writer", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Writer", + "text": "Writer" + }, "[]) => void" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", @@ -928,7 +1039,13 @@ "label": "writers", "description": [], "signature": [ - "Writer", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Writer", + "text": "Writer" + }, "[]" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", @@ -949,13 +1066,60 @@ "() => ", "Observable", "<", - "Message", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + }, ">" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", "deprecated": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLog.withType", + "type": "Function", + "tags": [], + "label": "withType", + "description": [ + "\nCreate a new ToolingLog which sets a different \"type\", allowing messages to be filtered out by \"source\"" + ], + "signature": [ + "(type: string) => ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.ToolingLog", + "text": "ToolingLog" + } + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLog.withType.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "A string that will be passed along with messages from this logger which can be used to filter messages with `ignoreSources`" + ], + "signature": [ + "string" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -1021,7 +1185,53 @@ "label": "level", "description": [], "signature": [ - "\"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"" + "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLogCollectingWriter.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [ + "\nCalled by ToolingLog, extends messages with the source if message includes one." + ], + "signature": [ + "(msg: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ") => boolean" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLogCollectingWriter.write.$1", + "type": "Object", + "tags": [], + "label": "msg", + "description": [], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + } ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", "deprecated": false, @@ -1049,7 +1259,13 @@ "text": "ToolingLogTextWriter" }, " implements ", - "Writer" + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Writer", + "text": "Writer" + } ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", "deprecated": false, @@ -1062,7 +1278,7 @@ "label": "level", "description": [], "signature": [ - "{ name: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"; flags: { warning: boolean; error: boolean; info: boolean; success: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" + "{ name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; info: boolean; success: boolean; warning: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", "deprecated": false @@ -1125,7 +1341,13 @@ "description": [], "signature": [ "(msg: ", - "Message", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + }, ") => boolean" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", @@ -1139,7 +1361,13 @@ "label": "msg", "description": [], "signature": [ - "Message" + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + } ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", "deprecated": false, @@ -1157,7 +1385,13 @@ "description": [], "signature": [ "(writeTo: { write(msg: string): void; }, prefix: string, msg: ", - "Message", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + }, ") => void" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", @@ -1199,7 +1433,13 @@ "label": "msg", "description": [], "signature": [ - "Message" + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + } ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", "deprecated": false, @@ -2455,7 +2695,7 @@ "label": "parseLogLevel", "description": [], "signature": [ - "(name: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\") => { name: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"; flags: { warning: boolean; error: boolean; info: boolean; success: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" + "(name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\") => { name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; info: boolean; success: boolean; warning: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" ], "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", "deprecated": false, @@ -2468,7 +2708,7 @@ "label": "name", "description": [], "signature": [ - "\"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"" + "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" ], "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", "deprecated": false, @@ -2486,7 +2726,7 @@ "label": "pickLevelFromFlags", "description": [], "signature": [ - "(flags: Record<string, string | boolean | string[] | undefined>, options: { default?: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\" | undefined; }) => \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"" + "(flags: Record<string, string | boolean | string[] | undefined>, options: { default?: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined; }) => \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" ], "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", "deprecated": false, @@ -2523,7 +2763,7 @@ "label": "default", "description": [], "signature": [ - "\"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\" | undefined" + "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined" ], "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", "deprecated": false @@ -2945,6 +3185,34 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.CiStatsMetadata", + "type": "Interface", + "tags": [], + "label": "CiStatsMetadata", + "description": [], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.CiStatsMetadata.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [ + "\nArbitrary key-value pairs which can be attached to CiStatsTiming and CiStatsMetric\nobjects stored in the ci-stats service" + ], + "signature": [ + "any" + ], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.CiStatsMetric", @@ -2961,7 +3229,9 @@ "type": "string", "tags": [], "label": "group", - "description": [], + "description": [ + "Top-level categorization for the metric, e.g. \"page load bundle size\"" + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false }, @@ -2971,7 +3241,9 @@ "type": "string", "tags": [], "label": "id", - "description": [], + "description": [ + "Specific sub-set of the \"group\", e.g. \"dashboard\"" + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false }, @@ -2981,7 +3253,9 @@ "type": "number", "tags": [], "label": "value", - "description": [], + "description": [ + "integer value recorded as the value of this metric" + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false }, @@ -2991,7 +3265,9 @@ "type": "number", "tags": [], "label": "limit", - "description": [], + "description": [ + "optional limit which will generate an error on PRs when the metric exceeds the limit" + ], "signature": [ "number | undefined" ], @@ -3004,33 +3280,59 @@ "type": "string", "tags": [], "label": "limitConfigPath", - "description": [], + "description": [ + "\npath, relative to the repo, where the config file contianing limits\nis kept. Linked from PR comments instructing contributors how to fix\ntheir PRs." + ], "signature": [ "string | undefined" ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming", - "type": "Interface", - "tags": [], - "label": "CiStatsTiming", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming.group", + "id": "def-server.CiStatsMetric.meta", + "type": "Object", + "tags": [], + "label": "meta", + "description": [ + "Arbitrary key-value pairs which can be used for additional filtering/reporting" + ], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.CiStatsMetadata", + "text": "CiStatsMetadata" + }, + " | undefined" + ], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.CiStatsTiming", + "type": "Interface", + "tags": [], + "label": "CiStatsTiming", + "description": [], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.CiStatsTiming.group", "type": "string", "tags": [], "label": "group", - "description": [], + "description": [ + "Top-level categorization for the timing, e.g. \"scripts/foo\", process type, etc." + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false }, @@ -3040,7 +3342,9 @@ "type": "string", "tags": [], "label": "id", - "description": [], + "description": [ + "Specific timing (witin the \"group\" being tracked) e.g. \"total\"" + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false }, @@ -3050,7 +3354,9 @@ "type": "number", "tags": [], "label": "ms", - "description": [], + "description": [ + "time in milliseconds which should be recorded" + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false }, @@ -3060,14 +3366,16 @@ "type": "Object", "tags": [], "label": "meta", - "description": [], + "description": [ + "hash of key-value pairs which will be stored with the timing for additional filtering and reporting" + ], "signature": [ { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsTimingMetadata", - "text": "CiStatsTimingMetadata" + "section": "def-server.CiStatsMetadata", + "text": "CiStatsMetadata" }, " | undefined" ], @@ -3077,32 +3385,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTimingMetadata", - "type": "Interface", - "tags": [], - "label": "CiStatsTimingMetadata", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTimingMetadata.Unnamed", - "type": "Any", - "tags": [], - "label": "Unnamed", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.Command", @@ -3226,6 +3508,45 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.Config", + "type": "Interface", + "tags": [], + "label": "Config", + "description": [ + "\nInformation about how CiStatsReporter should talk to the ci-stats service. Normally\nit is read from a JSON environment variable using the `parseConfig()` function\nexported by this module." + ], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.Config.apiToken", + "type": "string", + "tags": [], + "label": "apiToken", + "description": [ + "ApiToken necessary for writing build data to ci-stats service" + ], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.Config.buildId", + "type": "string", + "tags": [], + "label": "buildId", + "description": [ + "\nuuid which should be obtained by first creating a build with the\nci-stats service and then passing it to all subsequent steps" + ], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.FlagOptions", @@ -3480,54 +3801,105 @@ }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ReqOptions", + "id": "def-server.Message", "type": "Interface", "tags": [], - "label": "ReqOptions", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "label": "Message", + "description": [ + "\nThe object shape passed to ToolingLog writers each time the log is used." + ], + "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ReqOptions.auth", - "type": "boolean", + "id": "def-server.Message.type", + "type": "CompoundType", "tags": [], - "label": "auth", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "label": "type", + "description": [ + "level/type of message" + ], + "signature": [ + "\"write\" | \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"verbose\"" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", "deprecated": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ReqOptions.path", - "type": "string", + "id": "def-server.Message.indent", + "type": "number", "tags": [], - "label": "path", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "label": "indent", + "description": [ + "indentation intended when message written to a text log" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", "deprecated": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ReqOptions.body", - "type": "Any", + "id": "def-server.Message.source", + "type": "string", "tags": [], - "label": "body", - "description": [], + "label": "source", + "description": [ + "type of logger this message came from" + ], "signature": [ - "any" + "string | undefined" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", "deprecated": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ReqOptions.bodyDesc", - "type": "string", + "id": "def-server.Message.args", + "type": "Array", "tags": [], - "label": "bodyDesc", - "description": [], + "label": "args", + "description": [ + "args passed to the logging method" + ], + "signature": [ + "any[]" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.MetricsOptions", + "type": "Interface", + "tags": [], + "label": "MetricsOptions", + "description": [], + "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.MetricsOptions.defaultMeta", + "type": "Object", + "tags": [], + "label": "defaultMeta", + "description": [ + "Default metadata to add to each metric" + ], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.CiStatsMetadata", + "text": "CiStatsMetadata" + }, + " | undefined" + ], "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", "deprecated": false } @@ -3625,7 +3997,13 @@ "description": [], "signature": [ "(task: ", - "CleanupTask", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.CleanupTask", + "text": "CleanupTask" + }, ") => void" ], "path": "packages/kbn-dev-utils/src/run/run.ts", @@ -3639,7 +4017,13 @@ "label": "task", "description": [], "signature": [ - "CleanupTask" + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.CleanupTask", + "text": "CleanupTask" + } ], "path": "packages/kbn-dev-utils/src/run/run.ts", "deprecated": false, @@ -3695,7 +4079,7 @@ "label": "log", "description": [], "signature": [ - "{ defaultLevel?: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" + "{ defaultLevel?: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" ], "path": "packages/kbn-dev-utils/src/run/run.ts", "deprecated": false @@ -3751,7 +4135,7 @@ "label": "log", "description": [], "signature": [ - "{ defaultLevel?: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" + "{ defaultLevel?: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" ], "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false @@ -3914,6 +4298,56 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLogOptions", + "type": "Interface", + "tags": [], + "label": "ToolingLogOptions", + "description": [], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLogOptions.type", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "\ntype name for this logger, will be assigned to the \"source\"\nproperties of messages produced by this logger" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLogOptions.parent", + "type": "Object", + "tags": [], + "label": "parent", + "description": [ + "\nparent ToolingLog. When a ToolingLog has a parent they will both\nshare indent and writers state. Changing the indent width or\nwriters on either log will update the other too." + ], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.ToolingLog", + "text": "ToolingLog" + }, + " | undefined" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.ToolingLogTextWriterConfig", @@ -3930,9 +4364,26 @@ "type": "CompoundType", "tags": [], "label": "level", - "description": [], + "description": [ + "\nLog level, messages below this level will be ignored" + ], "signature": [ - "\"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"" + "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ToolingLogTextWriterConfig.ignoreSources", + "type": "Array", + "tags": [], + "label": "ignoreSources", + "description": [ + "\nList of message sources/ToolingLog types which will be ignored. Create\na logger with `ToolingLog#withType()` to create messages with a specific\nsource. Ignored messages will be dropped without writing." + ], + "signature": [ + "string[] | undefined" ], "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", "deprecated": false @@ -3943,7 +4394,9 @@ "type": "Object", "tags": [], "label": "writeTo", - "description": [], + "description": [ + "\nTarget which will receive formatted message lines, a common value for `writeTo`\nis process.stdout" + ], "signature": [ "{ write(s: string): void; }" ], @@ -3952,6 +4405,69 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.Writer", + "type": "Interface", + "tags": [], + "label": "Writer", + "description": [ + "\nAn object which received ToolingLog `Messages` and sends them to\nsome interface for collecting logs like stdio, or a file" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.Writer.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [ + "\nCalled with every log message, should return true if the message\nwas written and false if it was ignored." + ], + "signature": [ + "(msg: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ") => boolean" + ], + "path": "packages/kbn-dev-utils/src/tooling_log/writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.Writer.write.$1", + "type": "Object", + "tags": [], + "label": "msg", + "description": [ + "The log message to write" + ], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.Message", + "text": "Message" + } + ], + "path": "packages/kbn-dev-utils/src/tooling_log/writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false } ], "enums": [], @@ -3967,6 +4483,24 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.CleanupTask", + "type": "Type", + "tags": [], + "label": "CleanupTask", + "description": [ + "\nA function which will be called when the CLI is torn-down which should\nquickly cleanup whatever it needs." + ], + "signature": [ + "() => void" + ], + "path": "packages/kbn-dev-utils/src/run/cleanup.ts", + "deprecated": false, + "returnComment": [], + "children": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.CommandRunFn", @@ -4150,7 +4684,7 @@ "label": "LogLevel", "description": [], "signature": [ - "\"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"" + "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" ], "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", "deprecated": false, @@ -4164,7 +4698,7 @@ "label": "ParsedLogLevel", "description": [], "signature": [ - "{ name: \"warning\" | \"error\" | \"info\" | \"success\" | \"debug\" | \"silent\" | \"verbose\"; flags: { warning: boolean; error: boolean; info: boolean; success: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" + "{ name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; info: boolean; success: boolean; warning: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" ], "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", "deprecated": false, diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index c959baa6fda56..775e0c03fa49c 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 258 | 7 | 231 | 4 | +| 280 | 6 | 214 | 0 | ## Server diff --git a/api_docs/kbn_logging.json b/api_docs/kbn_logging.json index efb4d27831199..7a72a785c57e0 100644 --- a/api_docs/kbn_logging.json +++ b/api_docs/kbn_logging.json @@ -616,7 +616,7 @@ "label": "EcsEventCategory", "description": [], "signature": [ - "\"host\" | \"network\" | \"web\" | \"database\" | \"package\" | \"session\" | \"file\" | \"registry\" | \"process\" | \"authentication\" | \"configuration\" | \"driver\" | \"iam\" | \"intrusion_detection\" | \"malware\"" + "\"network\" | \"web\" | \"database\" | \"package\" | \"host\" | \"session\" | \"file\" | \"registry\" | \"process\" | \"authentication\" | \"configuration\" | \"driver\" | \"iam\" | \"intrusion_detection\" | \"malware\"" ], "path": "packages/kbn-logging/src/ecs/event.ts", "deprecated": false, @@ -658,7 +658,7 @@ "label": "EcsEventType", "description": [], "signature": [ - "\"start\" | \"connection\" | \"end\" | \"user\" | \"error\" | \"info\" | \"group\" | \"protocol\" | \"access\" | \"admin\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" + "\"start\" | \"end\" | \"user\" | \"error\" | \"info\" | \"connection\" | \"group\" | \"protocol\" | \"access\" | \"admin\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" ], "path": "packages/kbn-logging/src/ecs/event.ts", "deprecated": false, diff --git a/api_docs/kbn_monaco.json b/api_docs/kbn_monaco.json index b87619f900457..17323f36e0d89 100644 --- a/api_docs/kbn_monaco.json +++ b/api_docs/kbn_monaco.json @@ -274,7 +274,7 @@ "label": "kind", "description": [], "signature": [ - "\"type\" | \"keyword\" | \"field\" | \"property\" | \"method\" | \"class\" | \"constructor\"" + "\"keyword\" | \"type\" | \"field\" | \"property\" | \"method\" | \"class\" | \"constructor\"" ], "path": "packages/kbn-monaco/src/painless/types.ts", "deprecated": false @@ -369,7 +369,7 @@ "label": "PainlessCompletionKind", "description": [], "signature": [ - "\"type\" | \"keyword\" | \"field\" | \"property\" | \"method\" | \"class\" | \"constructor\"" + "\"keyword\" | \"type\" | \"field\" | \"property\" | \"method\" | \"class\" | \"constructor\"" ], "path": "packages/kbn-monaco/src/painless/types.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_autocomplete.json b/api_docs/kbn_securitysolution_autocomplete.json index 940a7d08d6155..293b1ad2f4e8d 100644 --- a/api_docs/kbn_securitysolution_autocomplete.json +++ b/api_docs/kbn_securitysolution_autocomplete.json @@ -274,7 +274,7 @@ "\nGiven an array of lists and optionally a field this will return all\nthe lists that match against the field based on the types from the field\n\nNOTE: That we support one additional property from \"FieldSpec\" located here:\nsrc/plugins/data/common/index_patterns/fields/types.ts\nThis type property is esTypes. If it exists and is on there we will read off the esTypes." ], "signature": [ - "(lists: { _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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[], field?: (", + "(lists: { _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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[], field?: (", { "pluginId": "@kbn/es-query", "scope": "common", @@ -282,7 +282,7 @@ "section": "def-common.DataViewFieldBase", "text": "DataViewFieldBase" }, - " & { esTypes?: string[] | undefined; }) | undefined) => { _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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" + " & { esTypes?: string[] | undefined; }) | undefined) => { _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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts", "deprecated": false, @@ -297,7 +297,7 @@ "The lists to match against the field" ], "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_es_utils.json b/api_docs/kbn_securitysolution_es_utils.json index 680d6993530dd..3a5bb6e97e90d 100644 --- a/api_docs/kbn_securitysolution_es_utils.json +++ b/api_docs/kbn_securitysolution_es_utils.json @@ -44,7 +44,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/create_boostrap_index/index.ts", "deprecated": false, @@ -59,7 +59,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/create_boostrap_index/index.ts", "deprecated": false, @@ -124,7 +124,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, pattern: string, maxAttempts?: number) => Promise<boolean>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, pattern: string, maxAttempts?: number) => Promise<boolean>" ], "path": "packages/kbn-securitysolution-es-utils/src/delete_all_index/index.ts", "deprecated": false, @@ -139,7 +139,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/delete_all_index/index.ts", "deprecated": false, @@ -187,7 +187,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, policy: string) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, policy: string) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/delete_policy/index.ts", "deprecated": false, @@ -202,7 +202,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/delete_policy/index.ts", "deprecated": false, @@ -236,7 +236,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, name: string) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, name: string) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/delete_template/index.ts", "deprecated": false, @@ -251,7 +251,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/delete_template/index.ts", "deprecated": false, @@ -320,7 +320,7 @@ "signature": [ "({ esClient, alias, }: { esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">; alias: string; }) => Promise<IndexAlias[]>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">; alias: string; }) => Promise<IndexAlias[]>" ], "path": "packages/kbn-securitysolution-es-utils/src/get_index_aliases/index.ts", "deprecated": false, @@ -343,27 +343,7 @@ "label": "esClient", "description": [], "signature": [ - "{ get: <TDocument = unknown, TContext = unknown>(params: ", - "GetRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined) => ", - "TransportRequestPromise", - "<", - "ApiResponse", - "<", - "GetResponse", - "<TDocument>, TContext>>; delete: <TContext = unknown>(params: ", - "DeleteRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined) => ", - "TransportRequestPromise", - "<", - "ApiResponse", - "<", - "DeleteResponse", - ", TContext>>; monitoring: { bulk<TContext = unknown>(params?: Record<string, any> | undefined, options?: ", + "{ monitoring: { bulk<TContext = unknown>(params?: Record<string, any> | undefined, options?: ", "TransportRequestOptions", " | undefined): ", "TransportRequestPromise", @@ -765,7 +745,27 @@ "ApiResponse", "<", "IndexResponse", - ", TContext>>; update: <TDocumentR = unknown, TDocument = unknown, TPartialDocument = unknown, TContext = unknown>(params: ", + ", TContext>>; delete: <TContext = unknown>(params: ", + "DeleteRequest", + ", options?: ", + "TransportRequestOptions", + " | undefined) => ", + "TransportRequestPromise", + "<", + "ApiResponse", + "<", + "DeleteResponse", + ", TContext>>; get: <TDocument = unknown, TContext = unknown>(params: ", + "GetRequest", + ", options?: ", + "TransportRequestOptions", + " | undefined) => ", + "TransportRequestPromise", + "<", + "ApiResponse", + "<", + "GetResponse", + "<TDocument>, TContext>>; update: <TDocumentR = unknown, TDocument = unknown, TPartialDocument = unknown, TContext = unknown>(params: ", "UpdateRequest", "<TDocument, TPartialDocument>, options?: ", "TransportRequestOptions", @@ -4120,7 +4120,7 @@ "signature": [ "({ esClient, index, }: { esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">; index: string; }) => Promise<number>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">; index: string; }) => Promise<number>" ], "path": "packages/kbn-securitysolution-es-utils/src/get_index_count/index.ts", "deprecated": false, @@ -4143,27 +4143,7 @@ "label": "esClient", "description": [], "signature": [ - "{ get: <TDocument = unknown, TContext = unknown>(params: ", - "GetRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined) => ", - "TransportRequestPromise", - "<", - "ApiResponse", - "<", - "GetResponse", - "<TDocument>, TContext>>; delete: <TContext = unknown>(params: ", - "DeleteRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined) => ", - "TransportRequestPromise", - "<", - "ApiResponse", - "<", - "DeleteResponse", - ", TContext>>; monitoring: { bulk<TContext = unknown>(params?: Record<string, any> | undefined, options?: ", + "{ monitoring: { bulk<TContext = unknown>(params?: Record<string, any> | undefined, options?: ", "TransportRequestOptions", " | undefined): ", "TransportRequestPromise", @@ -4565,7 +4545,27 @@ "ApiResponse", "<", "IndexResponse", - ", TContext>>; update: <TDocumentR = unknown, TDocument = unknown, TPartialDocument = unknown, TContext = unknown>(params: ", + ", TContext>>; delete: <TContext = unknown>(params: ", + "DeleteRequest", + ", options?: ", + "TransportRequestOptions", + " | undefined) => ", + "TransportRequestPromise", + "<", + "ApiResponse", + "<", + "DeleteResponse", + ", TContext>>; get: <TDocument = unknown, TContext = unknown>(params: ", + "GetRequest", + ", options?: ", + "TransportRequestOptions", + " | undefined) => ", + "TransportRequestPromise", + "<", + "ApiResponse", + "<", + "GetResponse", + "<TDocument>, TContext>>; update: <TDocumentR = unknown, TDocument = unknown, TPartialDocument = unknown, TContext = unknown>(params: ", "UpdateRequest", "<TDocument, TPartialDocument>, options?: ", "TransportRequestOptions", @@ -7918,7 +7918,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<boolean>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<boolean>" ], "path": "packages/kbn-securitysolution-es-utils/src/get_index_exists/index.ts", "deprecated": false, @@ -7933,7 +7933,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/get_index_exists/index.ts", "deprecated": false, @@ -7967,7 +7967,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, policy: string) => Promise<boolean>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, policy: string) => Promise<boolean>" ], "path": "packages/kbn-securitysolution-es-utils/src/get_policy_exists/index.ts", "deprecated": false, @@ -7982,7 +7982,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/get_policy_exists/index.ts", "deprecated": false, @@ -8016,7 +8016,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, template: string) => Promise<boolean>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, template: string) => Promise<boolean>" ], "path": "packages/kbn-securitysolution-es-utils/src/get_template_exists/index.ts", "deprecated": false, @@ -8031,7 +8031,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/get_template_exists/index.ts", "deprecated": false, @@ -8065,7 +8065,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/read_index/index.ts", "deprecated": false, @@ -8080,7 +8080,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/read_index/index.ts", "deprecated": false, @@ -8114,7 +8114,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, index: string) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/read_privileges/index.ts", "deprecated": false, @@ -8129,7 +8129,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/read_privileges/index.ts", "deprecated": false, @@ -8163,7 +8163,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, policy: string, body: Record<string, unknown>) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, policy: string, body: Record<string, unknown>) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/set_policy/index.ts", "deprecated": false, @@ -8178,7 +8178,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/set_policy/index.ts", "deprecated": false, @@ -8226,7 +8226,7 @@ "signature": [ "(esClient: Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, name: string, body: Record<string, unknown>) => Promise<unknown>" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">, name: string, body: Record<string, unknown>) => Promise<unknown>" ], "path": "packages/kbn-securitysolution-es-utils/src/set_template/index.ts", "deprecated": false, @@ -8241,7 +8241,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\">" ], "path": "packages/kbn-securitysolution-es-utils/src/set_template/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.json b/api_docs/kbn_securitysolution_io_ts_list_types.json index 2a1efcc96c5a7..7d10a90dac167 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.json +++ b/api_docs/kbn_securitysolution_io_ts_list_types.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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -40,7 +40,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -58,7 +58,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -71,7 +71,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -153,7 +153,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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 @@ -1216,7 +1216,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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 @@ -1307,7 +1307,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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 @@ -1890,7 +1890,7 @@ "label": "CreateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Pick<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; 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; }, \"type\" | \"description\" | \"name\" | \"meta\"> & { 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Pick<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; 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; }, \"type\" | \"description\" | \"name\" | \"meta\"> & { 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -1918,7 +1918,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -1932,7 +1932,7 @@ "label": "CreateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"description\" | \"name\" | \"meta\" | \"list_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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"description\" | \"name\" | \"meta\" | \"list_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -2002,7 +2002,7 @@ "label": "CreateListSchema", "description": [], "signature": [ - "{ description: string; name: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" + "{ description: string; name: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -2016,7 +2016,7 @@ "label": "CreateListSchemaDecoded", "description": [], "signature": [ - "{ type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; id: string | undefined; description: string; name: string; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" + "{ type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; id: string | undefined; description: string; name: string; 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, @@ -2310,7 +2310,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2324,7 +2324,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[] | 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[] | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2338,7 +2338,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -2366,7 +2366,7 @@ "label": "EntryList", "description": [], "signature": [ - "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" + "{ field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries_list/index.ts", "deprecated": false, @@ -2436,7 +2436,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -2744,7 +2744,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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; }" + "{ 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_exception_list_item_schema/index.ts", "deprecated": false, @@ -2772,7 +2772,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -2786,7 +2786,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -2856,7 +2856,7 @@ "label": "ImportListItemQuerySchema", "description": [], "signature": [ - "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" + "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -2870,7 +2870,7 @@ "label": "ImportListItemQuerySchemaEncoded", "description": [], "signature": [ - "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" + "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -2982,7 +2982,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -3024,7 +3024,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -3052,7 +3052,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -3080,7 +3080,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -3262,7 +3262,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -3276,7 +3276,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -3598,7 +3598,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -3612,7 +3612,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -3752,7 +3752,7 @@ "label": "Type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"" + "\"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -3766,7 +3766,7 @@ "label": "TypeOrUndefined", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined" + "\"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -3822,7 +3822,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -3836,7 +3836,7 @@ "label": "UpdateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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; }, \"type\" | \"id\" | \"description\" | \"name\" | \"meta\" | \"_version\" | \"os_types\" | \"item_id\"> & { 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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; }, \"type\" | \"id\" | \"description\" | \"name\" | \"meta\" | \"_version\" | \"os_types\" | \"item_id\"> & { 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -3850,7 +3850,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -3864,7 +3864,7 @@ "label": "UpdateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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; }, \"type\" | \"id\" | \"description\" | \"name\" | \"meta\" | \"_version\" | \"item_id\"> & { 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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; }, \"type\" | \"id\" | \"description\" | \"name\" | \"meta\" | \"_version\" | \"item_id\"> & { 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; 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, @@ -4341,7 +4341,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; list_id: ", "Type", "<string, string, unknown>; name: ", "StringC", @@ -7077,7 +7077,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -7902,7 +7902,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -7955,7 +7955,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { 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; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", diff --git a/api_docs/kbn_securitysolution_list_api.json b/api_docs/kbn_securitysolution_list_api.json index 7d6b00cbbc328..2c930b13c33b3 100644 --- a/api_docs/kbn_securitysolution_list_api.json +++ b/api_docs/kbn_securitysolution_list_api.json @@ -80,7 +80,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -248,7 +248,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -287,7 +287,7 @@ "signature": [ "({ deleteReferences, http, id, ignoreReferences, signal, }: ", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -453,7 +453,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -498,7 +498,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; }>" + ") => 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -582,7 +582,7 @@ "signature": [ "({ cursor, http, pageIndex, pageSize, signal, }: ", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -615,7 +615,7 @@ "signature": [ "({ file, http, listId, type, signal, }: ", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -785,7 +785,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, diff --git a/api_docs/kbn_securitysolution_list_hooks.json b/api_docs/kbn_securitysolution_list_hooks.json index bc26e83c859ac..a6dd6a78eefae 100644 --- a/api_docs/kbn_securitysolution_list_hooks.json +++ b/api_docs/kbn_securitysolution_list_hooks.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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -44,7 +44,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -66,7 +66,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": [ - "<T extends { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; }>(exceptionItem: T) => T" + "<T extends { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; }>(exceptionItem: T) => T" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -103,7 +103,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -118,7 +118,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -138,7 +138,7 @@ "label": "transformNewItemOutput", "description": [], "signature": [ - "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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, @@ -151,7 +151,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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, @@ -171,7 +171,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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, @@ -186,7 +186,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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, @@ -329,7 +329,7 @@ }, "<", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_delete_list/index.ts", "deprecated": false, @@ -493,7 +493,7 @@ }, "<", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -521,7 +521,7 @@ }, "<", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_import_list/index.ts", "deprecated": false, @@ -713,7 +713,7 @@ "label": "addExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -736,7 +736,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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 @@ -754,7 +754,7 @@ "label": "updateExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -777,7 +777,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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 @@ -891,7 +891,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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<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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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<void>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -911,7 +911,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -1116,7 +1116,7 @@ "label": "ReturnExceptionListAndItems", "description": [], "signature": [ - "[boolean, { _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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; }[], ", + "[boolean, { _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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; }[], ", { "pluginId": "@kbn/securitysolution-io-ts-list-types", "scope": "common", @@ -1176,7 +1176,7 @@ "label": "ReturnPersistExceptionItem", "description": [], "signature": [ - "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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_utils.json b/api_docs/kbn_securitysolution_list_utils.json index 5b956218f5ac8..5177d53b2acfb 100644 --- a/api_docs/kbn_securitysolution_list_utils.json +++ b/api_docs/kbn_securitysolution_list_utils.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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -40,7 +40,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -58,7 +58,7 @@ "label": "buildExceptionFilter", "description": [], "signature": [ - "({ lists, excludeExceptions, chunkSize, }: { lists: ({ _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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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; }))[]; excludeExceptions: boolean; chunkSize: number; }) => ", + "({ lists, excludeExceptions, chunkSize, }: { lists: ({ _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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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; }))[]; excludeExceptions: boolean; chunkSize: number; }) => ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -89,7 +89,7 @@ "label": "lists", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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-utils/src/build_exception_filter/index.ts", "deprecated": false @@ -696,7 +696,7 @@ "section": "def-common.ExceptionsBuilderExceptionItem", "text": "ExceptionsBuilderExceptionItem" }, - "[]) => ({ _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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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-utils/src/helpers/index.ts", "deprecated": false, @@ -968,7 +968,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } & { id?: string | undefined; }) | ({ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } & { id?: string | undefined; })" + ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } & { id?: string | undefined; }) | ({ field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } & { id?: string | undefined; })" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -1122,7 +1122,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -1167,7 +1167,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -2635,7 +2635,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -2648,7 +2648,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -3355,7 +3355,7 @@ "label": "BuilderEntry", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } & { id?: string | undefined; }) | ({ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } & { id?: string | undefined; }) | ", + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } & { id?: string | undefined; }) | ({ field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } & { id?: string | undefined; }) | ({ field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } & { id?: string | undefined; }) | ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3414,7 +3414,7 @@ "label": "CreateExceptionListItemBuilderSchema", "description": [], "signature": [ - "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"description\" | \"name\" | \"tags\" | \"comments\" | \"list_id\" | \"namespace_type\" | \"os_types\" | \"item_id\"> & { meta: { temporaryUuid: string; }; entries: ", + "Pick<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; 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\" | \"description\" | \"name\" | \"tags\" | \"comments\" | \"list_id\" | \"namespace_type\" | \"os_types\" | \"item_id\"> & { meta: { temporaryUuid: string; }; entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3548,7 +3548,7 @@ "label": "ExceptionListItemBuilderSchema", "description": [], "signature": [ - "Pick<{ _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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; }, \"type\" | \"id\" | \"description\" | \"name\" | \"tags\" | \"meta\" | \"updated_at\" | \"comments\" | \"_version\" | \"created_at\" | \"created_by\" | \"updated_by\" | \"tie_breaker_id\" | \"list_id\" | \"namespace_type\" | \"os_types\" | \"item_id\"> & { entries: ", + "Pick<{ _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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; }, \"type\" | \"id\" | \"description\" | \"name\" | \"tags\" | \"meta\" | \"updated_at\" | \"comments\" | \"_version\" | \"created_at\" | \"created_by\" | \"updated_by\" | \"tie_breaker_id\" | \"list_id\" | \"namespace_type\" | \"os_types\" | \"item_id\"> & { entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", diff --git a/api_docs/kbn_securitysolution_utils.json b/api_docs/kbn_securitysolution_utils.json index fc0556f7926a0..61eda7861af56 100644 --- a/api_docs/kbn_securitysolution_utils.json +++ b/api_docs/kbn_securitysolution_utils.json @@ -76,6 +76,37 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/securitysolution-utils", + "id": "def-server.transformDataToNdjson", + "type": "Function", + "tags": [], + "label": "transformDataToNdjson", + "description": [], + "signature": [ + "(data: unknown[]) => string" + ], + "path": "packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/securitysolution-utils", + "id": "def-server.transformDataToNdjson.$1", + "type": "Array", + "tags": [], + "label": "data", + "description": [], + "signature": [ + "unknown[]" + ], + "path": "packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [], diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 63039630e7c9a..23f9c42bfb9c4 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 2 | 0 | +| 6 | 0 | 4 | 0 | ## Server diff --git a/api_docs/kibana_react.json b/api_docs/kibana_react.json index 5d7a7241dd956..be973dd7ceb10 100644 --- a/api_docs/kibana_react.json +++ b/api_docs/kibana_react.json @@ -3416,7 +3416,7 @@ "label": "color", "description": [], "signature": [ - "\"warning\" | \"primary\" | \"success\" | \"danger\" | undefined" + "\"primary\" | \"success\" | \"warning\" | \"danger\" | undefined" ], "path": "src/plugins/kibana_react/public/notifications/types.ts", "deprecated": false @@ -3807,7 +3807,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -3939,7 +3939,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -4071,7 +4071,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -4203,7 +4203,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -4349,7 +4349,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -4481,7 +4481,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -4613,7 +4613,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -4745,7 +4745,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -5064,7 +5064,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -5196,7 +5196,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -5328,7 +5328,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", @@ -5460,7 +5460,7 @@ "DisambiguateSet", "<LabelAsString, LabelAsNode> & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; }> | undefined; display?: \"primary\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"transparent\" | \"plain\" | \"subdued\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; selectable?: (", "DisambiguateSet", "<", "PropsForAnchor", diff --git a/api_docs/kibana_utils.json b/api_docs/kibana_utils.json index 744c735e94d68..71174e6eafe3f 100644 --- a/api_docs/kibana_utils.json +++ b/api_docs/kibana_utils.json @@ -6895,7 +6895,7 @@ "signature": [ "(history: Pick<", "History", - "<any>, \"location\" | \"replace\">) => void" + "<any>, \"replace\" | \"location\">) => void" ], "path": "src/plugins/kibana_utils/public/plugin.ts", "deprecated": false, @@ -6910,7 +6910,7 @@ "signature": [ "Pick<", "History", - "<any>, \"location\" | \"replace\">" + "<any>, \"replace\" | \"location\">" ], "path": "src/plugins/kibana_utils/public/plugin.ts", "deprecated": false, diff --git a/api_docs/lens.json b/api_docs/lens.json index 18f6f3320f624..7dc468fcad234 100644 --- a/api_docs/lens.json +++ b/api_docs/lens.json @@ -332,7 +332,7 @@ "label": "operationType", "description": [], "signature": [ - "\"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"math\" | \"overall_sum\" | \"overall_min\" | \"overall_max\" | \"overall_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\" | \"formula\" | \"static_value\" | undefined" + "\"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"math\" | \"overall_sum\" | \"overall_min\" | \"overall_max\" | \"overall_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\" | \"formula\" | \"static_value\" | undefined" ], "path": "x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts", "deprecated": false @@ -2290,7 +2290,7 @@ "\nA union type of all available operation types. The operation type is a unique id of an operation.\nEach column is assigned to exactly one operation type." ], "signature": [ - "\"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"math\" | \"overall_sum\" | \"overall_min\" | \"overall_max\" | \"overall_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\" | \"formula\" | \"static_value\"" + "\"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"math\" | \"overall_sum\" | \"overall_min\" | \"overall_max\" | \"overall_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\" | \"formula\" | \"static_value\"" ], "path": "x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts", "deprecated": false, @@ -2911,7 +2911,7 @@ "label": "state", "description": [], "signature": [ - "{ datasourceMetaData: { filterableIndexPatterns: { id: string; title: string; }[]; }; datasourceStates: { indexpattern: { currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }; }; visualization: VisualizationState; query: ", + "{ datasourceMetaData: { filterableIndexPatterns: { id: string; title: string; }[]; }; datasourceStates: { indexpattern: { currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }; }; visualization: VisualizationState; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -3212,7 +3212,7 @@ "section": "def-server.LensDocShapePost712", "text": "LensDocShapePost712" }, - "<unknown>, \"title\" | \"expression\" | \"visualizationType\"> & { state: Pick<{ datasourceMetaData: { filterableIndexPatterns: { id: string; title: string; }[]; }; datasourceStates: { indexpattern: { currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }; }; visualization: unknown; query: ", + "<unknown>, \"title\" | \"expression\" | \"visualizationType\"> & { state: Pick<{ datasourceMetaData: { filterableIndexPatterns: { id: string; title: string; }[]; }; datasourceStates: { indexpattern: { currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }; }; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -3228,7 +3228,7 @@ "section": "def-common.Filter", "text": "Filter" }, - "[]; }, \"filters\" | \"query\" | \"visualization\" | \"datasourceMetaData\"> & { datasourceStates: { indexpattern: Pick<{ currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }, \"currentIndexPatternId\"> & { layers: Record<string, Pick<{ columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }, never> & { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; } | { operationType: \"date_histogram\"; params: { interval: string; timeZone?: string | undefined; }; }>; }>; }; }; }; }" + "[]; }, \"filters\" | \"query\" | \"visualization\" | \"datasourceMetaData\"> & { datasourceStates: { indexpattern: Pick<{ currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }, \"currentIndexPatternId\"> & { layers: Record<string, Pick<{ columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }, never> & { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; } | { operationType: \"date_histogram\"; params: { interval: string; timeZone?: string | undefined; }; }>; }>; }; }; }; }" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", "deprecated": false, @@ -3250,7 +3250,7 @@ "section": "def-server.LensDocShapePost712", "text": "LensDocShapePost712" }, - "<unknown>, \"title\" | \"expression\" | \"visualizationType\"> & { state: Pick<{ datasourceMetaData: { filterableIndexPatterns: { id: string; title: string; }[]; }; datasourceStates: { indexpattern: { currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }; }; visualization: unknown; query: ", + "<unknown>, \"title\" | \"expression\" | \"visualizationType\"> & { state: Pick<{ datasourceMetaData: { filterableIndexPatterns: { id: string; title: string; }[]; }; datasourceStates: { indexpattern: { currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }; }; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -3266,7 +3266,7 @@ "section": "def-common.Filter", "text": "Filter" }, - "[]; }, \"filters\" | \"query\" | \"visualization\" | \"datasourceMetaData\"> & { datasourceStates: { indexpattern: Pick<{ currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }, \"currentIndexPatternId\"> & { layers: Record<string, Pick<{ columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }, never> & { columns: Record<string, { operationType: \"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; } | { operationType: \"date_histogram\"; params: { interval: string; }; }>; }>; }; }; }; }" + "[]; }, \"filters\" | \"query\" | \"visualization\" | \"datasourceMetaData\"> & { datasourceStates: { indexpattern: Pick<{ currentIndexPatternId: string; layers: Record<string, { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }>; }, \"currentIndexPatternId\"> & { layers: Record<string, Pick<{ columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; }>; }, never> & { columns: Record<string, { operationType: \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"; } | { operationType: \"date_histogram\"; params: { interval: string; }; }>; }>; }; }; }; }" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", "deprecated": false, @@ -3280,7 +3280,7 @@ "label": "OperationTypePost712", "description": [], "signature": [ - "\"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"" + "\"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\"" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", "deprecated": false, @@ -3294,7 +3294,7 @@ "label": "OperationTypePre712", "description": [], "signature": [ - "\"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"percentile\" | \"terms\" | \"avg\" | \"median\" | \"cumulative_sum\" | \"derivative\" | \"moving_average\" | \"cardinality\" | \"counter_rate\" | \"last_value\"" + "\"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"percentile\" | \"range\" | \"terms\" | \"avg\" | \"median\" | \"cumulative_sum\" | \"derivative\" | \"moving_average\" | \"cardinality\" | \"counter_rate\" | \"last_value\"" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", "deprecated": false, @@ -4244,13 +4244,21 @@ "signature": [ "(mapping?: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined) => ", + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined) => ", { "pluginId": "fieldFormats", "scope": "common", @@ -4272,13 +4280,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined" ], "path": "x-pack/plugins/lens/common/types.ts", "deprecated": false diff --git a/api_docs/lists.json b/api_docs/lists.json index d6e2a97fa78ab..b3d498a4532d3 100644 --- a/api_docs/lists.json +++ b/api_docs/lists.json @@ -410,7 +410,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -480,7 +480,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -514,7 +514,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -548,7 +548,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -682,7 +682,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -726,7 +726,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -764,7 +764,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -830,7 +830,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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, @@ -862,7 +862,7 @@ "signature": [ "({ listId, filter, perPage, page, 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -894,7 +894,7 @@ "signature": [ "({ listId, filter, perPage, page, 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -926,7 +926,7 @@ "signature": [ "({ perPage, page, 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -992,7 +992,7 @@ "signature": [ "({ filter, perPage, page, 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1097,7 +1097,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1129,7 +1129,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1161,7 +1161,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1493,7 +1493,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1525,7 +1525,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1557,7 +1557,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1621,7 +1621,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1653,7 +1653,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1685,7 +1685,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1717,7 +1717,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1749,7 +1749,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1781,7 +1781,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1813,7 +1813,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1845,7 +1845,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1877,7 +1877,7 @@ "signature": [ "({ filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, }: ", "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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -1909,7 +1909,7 @@ "signature": [ "({ listId, filter, currentIndexPosition, perPage, page, 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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_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, @@ -1968,7 +1968,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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 @@ -2182,7 +2182,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_range\" | \"date_range\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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\" | \"keyword\" | \"ip_range\" | \"date_range\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"ip\" | \"long\" | \"double\" | \"text\" | \"date_nanos\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; 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 @@ -2337,7 +2337,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, user: string) => ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, user: string) => ", { "pluginId": "lists", "scope": "server", @@ -2358,25 +2358,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -2434,7 +2416,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -2498,6 +2488,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", @@ -2738,7 +2738,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", diff --git a/api_docs/maps_ems.json b/api_docs/maps_ems.json index 7d2d8d9eefddc..dd5f8d905952d 100644 --- a/api_docs/maps_ems.json +++ b/api_docs/maps_ems.json @@ -908,7 +908,7 @@ "label": "DEFAULT_EMS_LANDING_PAGE_URL", "description": [], "signature": [ - "\"https://maps.elastic.co/v7.15\"" + "\"https://maps.elastic.co/v7.16\"" ], "path": "src/plugins/maps_ems/common/index.ts", "deprecated": false, diff --git a/api_docs/metrics_entities.json b/api_docs/metrics_entities.json index 6b7d685b46939..601c41a282257 100644 --- a/api_docs/metrics_entities.json +++ b/api_docs/metrics_entities.json @@ -58,7 +58,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", diff --git a/api_docs/ml.json b/api_docs/ml.json index 102e433e4600e..d5f9d552690c1 100644 --- a/api_docs/ml.json +++ b/api_docs/ml.json @@ -1055,7 +1055,7 @@ }, "<", "MlAnomalyDetectionAlertParams", - ">, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[] | undefined" + ">, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[] | undefined" ], "path": "x-pack/plugins/ml/common/types/anomaly_detection_jobs/summary_job.ts", "deprecated": false @@ -2890,7 +2890,7 @@ }, "<", "MlAnomalyDetectionAlertParams", - ">, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[] | undefined" + ">, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[] | undefined" ], "path": "x-pack/plugins/ml/common/types/anomaly_detection_jobs/summary_job.ts", "deprecated": false @@ -3434,7 +3434,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, request: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">, request: ", { "pluginId": "core", "scope": "server", diff --git a/api_docs/monitoring.json b/api_docs/monitoring.json index ddeba9737dc2d..0de686a2108eb 100644 --- a/api_docs/monitoring.json +++ b/api_docs/monitoring.json @@ -149,7 +149,7 @@ "signature": [ "{ ui: { elasticsearch: ", "MonitoringElasticsearchConfig", - "; enabled: boolean; container: Readonly<{} & { logstash: Readonly<{} & { enabled: boolean; }>; apm: Readonly<{} & { enabled: boolean; }>; elasticsearch: Readonly<{} & { enabled: boolean; }>; }>; logs: Readonly<{} & { index: string; }>; metricbeat: Readonly<{} & { index: string; }>; debug_mode: boolean; debug_log_path: string; ccs: Readonly<{} & { enabled: boolean; }>; max_bucket_size: number; min_interval_seconds: number; show_license_expiration: boolean; render_react_app: boolean; }; enabled: boolean; kibana: Readonly<{} & { collection: Readonly<{} & { enabled: boolean; interval: number; }>; }>; licensing: Readonly<{} & { api_polling_frequency: moment.Duration; }>; agent: Readonly<{} & { interval: string; }>; cluster_alerts: Readonly<{} & { enabled: boolean; allowedSpaces: string[]; email_notifications: Readonly<{} & { enabled: boolean; email_address: string; }>; }>; tests: Readonly<{} & { cloud_detector: Readonly<{} & { enabled: boolean; }>; }>; }" + "; enabled: boolean; container: Readonly<{} & { logstash: Readonly<{} & { enabled: boolean; }>; apm: Readonly<{} & { enabled: boolean; }>; elasticsearch: Readonly<{} & { enabled: boolean; }>; }>; logs: Readonly<{} & { index: string; }>; metricbeat: Readonly<{} & { index: string; }>; debug_mode: boolean; debug_log_path: string; ccs: Readonly<{} & { enabled: boolean; }>; max_bucket_size: number; min_interval_seconds: number; show_license_expiration: boolean; render_react_app: boolean; }; tests: Readonly<{} & { cloud_detector: Readonly<{} & { enabled: boolean; }>; }>; enabled: boolean; kibana: Readonly<{} & { collection: Readonly<{} & { interval: number; enabled: boolean; }>; }>; licensing: Readonly<{} & { api_polling_frequency: moment.Duration; }>; agent: Readonly<{} & { interval: string; }>; cluster_alerts: Readonly<{} & { enabled: boolean; allowedSpaces: string[]; email_notifications: Readonly<{} & { enabled: boolean; email_address: string; }>; }>; }" ], "path": "x-pack/plugins/monitoring/server/config.ts", "deprecated": false, diff --git a/api_docs/observability.json b/api_docs/observability.json index aa66c500c05e5..3889631a20bec 100644 --- a/api_docs/observability.json +++ b/api_docs/observability.json @@ -438,7 +438,7 @@ "label": "LazyAlertsFlyout", "description": [], "signature": [ - "React.ExoticComponent<Pick<AlertsFlyoutProps, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"key\" | \"id\" | \"title\" | \"security\" | \"size\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"paddingSize\" | \"data-test-subj\" | \"alert\" | \"onClose\" | \"css\" | \"as\" | \"ownFocus\" | \"alerts\" | \"maxWidth\" | \"hideCloseButton\" | \"closeButtonAriaLabel\" | \"closeButtonProps\" | \"closeButtonPosition\" | \"maskProps\" | \"outsideClickCloses\" | \"side\" | \"pushMinBreakpoint\" | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject<HTMLDivElement> | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" + "React.ExoticComponent<Pick<AlertsFlyoutProps, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"key\" | \"type\" | \"id\" | \"title\" | \"security\" | \"size\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"paddingSize\" | \"data-test-subj\" | \"alert\" | \"onClose\" | \"css\" | \"as\" | \"ownFocus\" | \"alerts\" | \"maxWidth\" | \"hideCloseButton\" | \"closeButtonAriaLabel\" | \"closeButtonProps\" | \"closeButtonPosition\" | \"maskProps\" | \"outsideClickCloses\" | \"side\" | \"pushMinBreakpoint\" | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject<HTMLDivElement> | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" ], "path": "x-pack/plugins/observability/public/index.ts", "deprecated": false, @@ -1029,7 +1029,7 @@ "label": "useUiTracker", "description": [], "signature": [ - "({\n app: defaultApp,\n}: { app?: \"fleet\" | \"apm\" | \"infra_metrics\" | \"infra_logs\" | \"uptime\" | \"synthetics\" | \"observability-overview\" | \"stack_monitoring\" | \"ux\" | undefined; }) => ({ app, metric, metricType }: ", + "({\n app: defaultApp,\n}: { app?: \"fleet\" | \"apm\" | \"synthetics\" | \"infra_metrics\" | \"infra_logs\" | \"uptime\" | \"observability-overview\" | \"stack_monitoring\" | \"ux\" | undefined; }) => ({ app, metric, metricType }: ", { "pluginId": "observability", "scope": "public", @@ -1060,7 +1060,7 @@ "label": "app", "description": [], "signature": [ - "\"fleet\" | \"apm\" | \"infra_metrics\" | \"infra_logs\" | \"uptime\" | \"synthetics\" | \"observability-overview\" | \"stack_monitoring\" | \"ux\" | undefined" + "\"fleet\" | \"apm\" | \"synthetics\" | \"infra_metrics\" | \"infra_logs\" | \"uptime\" | \"observability-overview\" | \"stack_monitoring\" | \"ux\" | undefined" ], "path": "x-pack/plugins/observability/public/hooks/use_track_metric.tsx", "deprecated": false @@ -2517,7 +2517,7 @@ "label": "operationType", "description": [], "signature": [ - "\"range\" | \"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"math\" | \"overall_sum\" | \"overall_min\" | \"overall_max\" | \"overall_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\" | \"formula\" | \"static_value\" | undefined" + "\"filters\" | \"max\" | \"min\" | \"count\" | \"date_histogram\" | \"sum\" | \"average\" | \"percentile\" | \"range\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"math\" | \"overall_sum\" | \"overall_min\" | \"overall_max\" | \"overall_average\" | \"counter_rate\" | \"differences\" | \"unique_count\" | \"last_value\" | \"formula\" | \"static_value\" | undefined" ], "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts", "deprecated": false @@ -2530,7 +2530,7 @@ "label": "dataType", "description": [], "signature": [ - "\"mobile\" | \"apm\" | \"infra_metrics\" | \"infra_logs\" | \"synthetics\" | \"ux\"" + "\"mobile\" | \"apm\" | \"synthetics\" | \"infra_metrics\" | \"infra_logs\" | \"ux\"" ], "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts", "deprecated": false @@ -3233,7 +3233,7 @@ "label": "ObservabilityFetchDataPlugins", "description": [], "signature": [ - "\"apm\" | \"infra_metrics\" | \"infra_logs\" | \"synthetics\" | \"ux\"" + "\"apm\" | \"synthetics\" | \"infra_metrics\" | \"infra_logs\" | \"ux\"" ], "path": "x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts", "deprecated": false, @@ -3316,27 +3316,27 @@ "DisambiguateSet", "<(", "DisambiguateSet", - "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", + "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", "DisambiguateSet", - "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>), React.HTMLAttributes<HTMLSpanElement>> & React.HTMLAttributes<HTMLSpanElement>) | (", + "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>), React.HTMLAttributes<HTMLSpanElement>> & React.HTMLAttributes<HTMLSpanElement>) | (", "DisambiguateSet", "<React.HTMLAttributes<HTMLSpanElement>, (", "DisambiguateSet", - "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", + "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", "DisambiguateSet", - "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>)> & ", + "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>)> & ", "DisambiguateSet", - "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", + "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", "DisambiguateSet", "<React.HTMLAttributes<HTMLSpanElement>, (", "DisambiguateSet", - "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", + "<React.ButtonHTMLAttributes<HTMLButtonElement>, Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">> & Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">) | (", "DisambiguateSet", - "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>)> & ", + "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>)> & ", "DisambiguateSet", - "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"type\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>), \"children\" | \"type\" | \"onChange\" | \"onKeyDown\" | \"id\" | \"title\" | \"security\" | \"name\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"autoFocus\" | \"disabled\" | \"form\" | \"formAction\" | \"formEncType\" | \"formMethod\" | \"formNoValidate\" | \"formTarget\" | \"value\" | \"media\" | \"download\" | \"ping\" | \"hrefLang\" | \"referrerPolicy\"> & { size?: \"m\" | \"s\" | \"l\" | \"xs\" | undefined; color?: \"text\" | \"primary\" | \"inherit\" | \"ghost\" | \"subdued\" | undefined; label: React.ReactNode; isActive?: boolean | undefined; isDisabled?: boolean | undefined; href?: string | undefined; target?: string | undefined; rel?: string | undefined; iconType?: string | React.ComponentClass<{}, any> | React.FunctionComponent<{}> | undefined; iconProps?: Pick<", + "<Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"media\" | \"target\" | \"download\" | \"ping\" | \"hrefLang\" | \"rel\" | \"referrerPolicy\">, React.ButtonHTMLAttributes<HTMLButtonElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>), \"children\" | \"onChange\" | \"onKeyDown\" | \"type\" | \"id\" | \"title\" | \"security\" | \"name\" | \"defaultChecked\" | \"defaultValue\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"className\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"hidden\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"autoFocus\" | \"disabled\" | \"form\" | \"formAction\" | \"formEncType\" | \"formMethod\" | \"formNoValidate\" | \"formTarget\" | \"value\" | \"media\" | \"download\" | \"ping\" | \"hrefLang\" | \"referrerPolicy\"> & { size?: \"m\" | \"s\" | \"l\" | \"xs\" | undefined; color?: \"text\" | \"primary\" | \"inherit\" | \"ghost\" | \"subdued\" | undefined; label: React.ReactNode; isActive?: boolean | undefined; isDisabled?: boolean | undefined; href?: string | undefined; target?: string | undefined; rel?: string | undefined; iconType?: string | React.ComponentClass<{}, any> | React.FunctionComponent<{}> | undefined; iconProps?: Pick<", "EuiIconProps", - ", \"string\" | \"children\" | \"from\" | \"origin\" | \"cursor\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"y\" | \"d\" | \"x\" | \"id\" | \"title\" | \"operator\" | \"name\" | \"version\" | \"filter\" | \"size\" | \"format\" | \"order\" | \"className\" | \"lang\" | \"style\" | \"tabIndex\" | \"role\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"height\" | \"max\" | \"media\" | \"method\" | \"min\" | \"target\" | \"width\" | \"crossOrigin\" | \"accentHeight\" | \"accumulate\" | \"additive\" | \"alignmentBaseline\" | \"allowReorder\" | \"alphabetic\" | \"amplitude\" | \"arabicForm\" | \"ascent\" | \"attributeName\" | \"attributeType\" | \"autoReverse\" | \"azimuth\" | \"baseFrequency\" | \"baselineShift\" | \"baseProfile\" | \"bbox\" | \"begin\" | \"bias\" | \"by\" | \"calcMode\" | \"capHeight\" | \"clip\" | \"clipPath\" | \"clipPathUnits\" | \"clipRule\" | \"colorInterpolation\" | \"colorInterpolationFilters\" | \"colorProfile\" | \"colorRendering\" | \"contentScriptType\" | \"contentStyleType\" | \"cx\" | \"cy\" | \"decelerate\" | \"descent\" | \"diffuseConstant\" | \"direction\" | \"display\" | \"divisor\" | \"dominantBaseline\" | \"dur\" | \"dx\" | \"dy\" | \"edgeMode\" | \"elevation\" | \"enableBackground\" | \"end\" | \"exponent\" | \"externalResourcesRequired\" | \"fill\" | \"fillOpacity\" | \"fillRule\" | \"filterRes\" | \"filterUnits\" | \"floodColor\" | \"floodOpacity\" | \"focusable\" | \"fontFamily\" | \"fontSize\" | \"fontSizeAdjust\" | \"fontStretch\" | \"fontStyle\" | \"fontVariant\" | \"fontWeight\" | \"fx\" | \"fy\" | \"g1\" | \"g2\" | \"glyphName\" | \"glyphOrientationHorizontal\" | \"glyphOrientationVertical\" | \"glyphRef\" | \"gradientTransform\" | \"gradientUnits\" | \"hanging\" | \"horizAdvX\" | \"horizOriginX\" | \"href\" | \"ideographic\" | \"imageRendering\" | \"in2\" | \"in\" | \"intercept\" | \"k1\" | \"k2\" | \"k3\" | \"k4\" | \"k\" | \"kernelMatrix\" | \"kernelUnitLength\" | \"kerning\" | \"keyPoints\" | \"keySplines\" | \"keyTimes\" | \"lengthAdjust\" | \"letterSpacing\" | \"lightingColor\" | \"limitingConeAngle\" | \"local\" | \"markerEnd\" | \"markerHeight\" | \"markerMid\" | \"markerStart\" | \"markerUnits\" | \"markerWidth\" | \"mask\" | \"maskContentUnits\" | \"maskUnits\" | \"mathematical\" | \"mode\" | \"numOctaves\" | \"offset\" | \"opacity\" | \"orient\" | \"orientation\" | \"overflow\" | \"overlinePosition\" | \"overlineThickness\" | \"paintOrder\" | \"panose1\" | \"path\" | \"pathLength\" | \"patternContentUnits\" | \"patternTransform\" | \"patternUnits\" | \"pointerEvents\" | \"points\" | \"pointsAtX\" | \"pointsAtY\" | \"pointsAtZ\" | \"preserveAlpha\" | \"preserveAspectRatio\" | \"primitiveUnits\" | \"r\" | \"radius\" | \"refX\" | \"refY\" | \"renderingIntent\" | \"repeatCount\" | \"repeatDur\" | \"requiredExtensions\" | \"requiredFeatures\" | \"restart\" | \"result\" | \"rotate\" | \"rx\" | \"ry\" | \"scale\" | \"seed\" | \"shapeRendering\" | \"slope\" | \"spacing\" | \"specularConstant\" | \"specularExponent\" | \"speed\" | \"spreadMethod\" | \"startOffset\" | \"stdDeviation\" | \"stemh\" | \"stemv\" | \"stitchTiles\" | \"stopColor\" | \"stopOpacity\" | \"strikethroughPosition\" | \"strikethroughThickness\" | \"stroke\" | \"strokeDasharray\" | \"strokeDashoffset\" | \"strokeLinecap\" | \"strokeLinejoin\" | \"strokeMiterlimit\" | \"strokeOpacity\" | \"strokeWidth\" | \"surfaceScale\" | \"systemLanguage\" | \"tableValues\" | \"targetX\" | \"targetY\" | \"textAnchor\" | \"textDecoration\" | \"textLength\" | \"textRendering\" | \"to\" | \"transform\" | \"u1\" | \"u2\" | \"underlinePosition\" | \"underlineThickness\" | \"unicode\" | \"unicodeBidi\" | \"unicodeRange\" | \"unitsPerEm\" | \"vAlphabetic\" | \"values\" | \"vectorEffect\" | \"vertAdvY\" | \"vertOriginX\" | \"vertOriginY\" | \"vHanging\" | \"vIdeographic\" | \"viewBox\" | \"viewTarget\" | \"visibility\" | \"vMathematical\" | \"widths\" | \"wordSpacing\" | \"writingMode\" | \"x1\" | \"x2\" | \"xChannelSelector\" | \"xHeight\" | \"xlinkActuate\" | \"xlinkArcrole\" | \"xlinkHref\" | \"xlinkRole\" | \"xlinkShow\" | \"xlinkTitle\" | \"xlinkType\" | \"xmlBase\" | \"xmlLang\" | \"xmlns\" | \"xmlnsXlink\" | \"xmlSpace\" | \"y1\" | \"y2\" | \"yChannelSelector\" | \"z\" | \"zoomAndPan\" | \"titleId\" | \"onIconLoad\"> | undefined; icon?: React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)> | undefined; showToolTip?: boolean | undefined; extraAction?: ({ type?: \"reset\" | \"button\" | \"submit\" | undefined; } & ", + ", \"string\" | \"children\" | \"cursor\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"y\" | \"d\" | \"x\" | \"id\" | \"title\" | \"operator\" | \"name\" | \"version\" | \"filter\" | \"from\" | \"size\" | \"format\" | \"order\" | \"className\" | \"lang\" | \"style\" | \"tabIndex\" | \"role\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"height\" | \"max\" | \"media\" | \"method\" | \"min\" | \"target\" | \"width\" | \"crossOrigin\" | \"accentHeight\" | \"accumulate\" | \"additive\" | \"alignmentBaseline\" | \"allowReorder\" | \"alphabetic\" | \"amplitude\" | \"arabicForm\" | \"ascent\" | \"attributeName\" | \"attributeType\" | \"autoReverse\" | \"azimuth\" | \"baseFrequency\" | \"baselineShift\" | \"baseProfile\" | \"bbox\" | \"begin\" | \"bias\" | \"by\" | \"calcMode\" | \"capHeight\" | \"clip\" | \"clipPath\" | \"clipPathUnits\" | \"clipRule\" | \"colorInterpolation\" | \"colorInterpolationFilters\" | \"colorProfile\" | \"colorRendering\" | \"contentScriptType\" | \"contentStyleType\" | \"cx\" | \"cy\" | \"decelerate\" | \"descent\" | \"diffuseConstant\" | \"direction\" | \"display\" | \"divisor\" | \"dominantBaseline\" | \"dur\" | \"dx\" | \"dy\" | \"edgeMode\" | \"elevation\" | \"enableBackground\" | \"end\" | \"exponent\" | \"externalResourcesRequired\" | \"fill\" | \"fillOpacity\" | \"fillRule\" | \"filterRes\" | \"filterUnits\" | \"floodColor\" | \"floodOpacity\" | \"focusable\" | \"fontFamily\" | \"fontSize\" | \"fontSizeAdjust\" | \"fontStretch\" | \"fontStyle\" | \"fontVariant\" | \"fontWeight\" | \"fx\" | \"fy\" | \"g1\" | \"g2\" | \"glyphName\" | \"glyphOrientationHorizontal\" | \"glyphOrientationVertical\" | \"glyphRef\" | \"gradientTransform\" | \"gradientUnits\" | \"hanging\" | \"horizAdvX\" | \"horizOriginX\" | \"href\" | \"ideographic\" | \"imageRendering\" | \"in2\" | \"in\" | \"intercept\" | \"k1\" | \"k2\" | \"k3\" | \"k4\" | \"k\" | \"kernelMatrix\" | \"kernelUnitLength\" | \"kerning\" | \"keyPoints\" | \"keySplines\" | \"keyTimes\" | \"lengthAdjust\" | \"letterSpacing\" | \"lightingColor\" | \"limitingConeAngle\" | \"local\" | \"markerEnd\" | \"markerHeight\" | \"markerMid\" | \"markerStart\" | \"markerUnits\" | \"markerWidth\" | \"mask\" | \"maskContentUnits\" | \"maskUnits\" | \"mathematical\" | \"mode\" | \"numOctaves\" | \"offset\" | \"opacity\" | \"orient\" | \"orientation\" | \"origin\" | \"overflow\" | \"overlinePosition\" | \"overlineThickness\" | \"paintOrder\" | \"panose1\" | \"path\" | \"pathLength\" | \"patternContentUnits\" | \"patternTransform\" | \"patternUnits\" | \"pointerEvents\" | \"points\" | \"pointsAtX\" | \"pointsAtY\" | \"pointsAtZ\" | \"preserveAlpha\" | \"preserveAspectRatio\" | \"primitiveUnits\" | \"r\" | \"radius\" | \"refX\" | \"refY\" | \"renderingIntent\" | \"repeatCount\" | \"repeatDur\" | \"requiredExtensions\" | \"requiredFeatures\" | \"restart\" | \"result\" | \"rotate\" | \"rx\" | \"ry\" | \"scale\" | \"seed\" | \"shapeRendering\" | \"slope\" | \"spacing\" | \"specularConstant\" | \"specularExponent\" | \"speed\" | \"spreadMethod\" | \"startOffset\" | \"stdDeviation\" | \"stemh\" | \"stemv\" | \"stitchTiles\" | \"stopColor\" | \"stopOpacity\" | \"strikethroughPosition\" | \"strikethroughThickness\" | \"stroke\" | \"strokeDasharray\" | \"strokeDashoffset\" | \"strokeLinecap\" | \"strokeLinejoin\" | \"strokeMiterlimit\" | \"strokeOpacity\" | \"strokeWidth\" | \"surfaceScale\" | \"systemLanguage\" | \"tableValues\" | \"targetX\" | \"targetY\" | \"textAnchor\" | \"textDecoration\" | \"textLength\" | \"textRendering\" | \"to\" | \"transform\" | \"u1\" | \"u2\" | \"underlinePosition\" | \"underlineThickness\" | \"unicode\" | \"unicodeBidi\" | \"unicodeRange\" | \"unitsPerEm\" | \"vAlphabetic\" | \"values\" | \"vectorEffect\" | \"vertAdvY\" | \"vertOriginX\" | \"vertOriginY\" | \"vHanging\" | \"vIdeographic\" | \"viewBox\" | \"viewTarget\" | \"visibility\" | \"vMathematical\" | \"widths\" | \"wordSpacing\" | \"writingMode\" | \"x1\" | \"x2\" | \"xChannelSelector\" | \"xHeight\" | \"xlinkActuate\" | \"xlinkArcrole\" | \"xlinkHref\" | \"xlinkRole\" | \"xlinkShow\" | \"xlinkTitle\" | \"xlinkType\" | \"xmlBase\" | \"xmlLang\" | \"xmlns\" | \"xmlnsXlink\" | \"xmlSpace\" | \"y1\" | \"y2\" | \"yChannelSelector\" | \"z\" | \"zoomAndPan\" | \"titleId\" | \"onIconLoad\"> | undefined; icon?: React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)> | undefined; showToolTip?: boolean | undefined; extraAction?: ({ type?: \"reset\" | \"button\" | \"submit\" | undefined; } & ", "EuiButtonIconProps", " & { onClick?: ((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void) | undefined; } & React.ButtonHTMLAttributes<HTMLButtonElement> & { buttonRef?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined; } & { alwaysShow?: boolean | undefined; }) | undefined; onClick?: ((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void) | undefined; wrapText?: boolean | undefined; buttonRef?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined; }" ], @@ -3420,7 +3420,7 @@ "label": "ObservabilityPublicSetup", "description": [], "signature": [ - "{ dashboard: { register: <T extends \"apm\" | \"infra_metrics\" | \"infra_logs\" | \"synthetics\" | \"ux\">({ appName, fetchData, hasData, }: { appName: T; } & ", + "{ dashboard: { register: <T extends \"apm\" | \"synthetics\" | \"infra_metrics\" | \"infra_logs\" | \"ux\">({ appName, fetchData, hasData, }: { appName: T; } & ", { "pluginId": "observability", "scope": "public", @@ -3683,7 +3683,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 533a86b9e806f..19e3bc08a5361 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -12,13 +12,13 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Count | Plugins or Packages with a <br /> public API | Number of teams | |--------------|----------|------------------------| -| 202 | 158 | 32 | +| 200 | 157 | 32 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 24409 | 277 | 19821 | 1585 | +| 24459 | 276 | 19826 | 1583 | ## Plugin Directory @@ -26,27 +26,26 @@ warning: This document is auto-generated and is meant to be viewed inside our ex |--------------|----------------|-----------|--------------|----------|---------------|--------| | <DocLink id="kibActionsPluginApi" text="actions"/> | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 125 | 0 | 125 | 8 | | <DocLink id="kibAdvancedSettingsPluginApi" text="advancedSettings"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 23 | 0 | 22 | 1 | -| <DocLink id="kibAlertingPluginApi" text="alerting"/> | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 249 | 0 | 241 | 17 | -| <DocLink id="kibApmPluginApi" text="apm"/> | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 42 | 0 | 42 | 37 | -| <DocLink id="kibApmOssPluginApi" text="apmOss"/> | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | - | 6 | 0 | 6 | 0 | +| <DocLink id="kibAlertingPluginApi" text="alerting"/> | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 257 | 0 | 249 | 17 | +| <DocLink id="kibApmPluginApi" text="apm"/> | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 39 | 0 | 39 | 37 | | <DocLink id="kibBannersPluginApi" text="banners"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | -| <DocLink id="kibBfetchPluginApi" text="bfetch"/> | [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. | 77 | 1 | 66 | 2 | +| <DocLink id="kibBfetchPluginApi" text="bfetch"/> | [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. | 76 | 1 | 67 | 2 | | <DocLink id="kibCanvasPluginApi" text="canvas"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | -| <DocLink id="kibCasesPluginApi" text="cases"/> | [Security Solution Threat Hunting](https://github.com/orgs/elastic/teams/security-threat-hunting) | The Case management system in Kibana | 475 | 0 | 431 | 14 | +| <DocLink id="kibCasesPluginApi" text="cases"/> | [Security Solution Threat Hunting](https://github.com/orgs/elastic/teams/security-threat-hunting) | The Case management system in Kibana | 476 | 0 | 432 | 14 | | <DocLink id="kibChartsPluginApi" text="charts"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 285 | 4 | 253 | 3 | | <DocLink id="kibCloudPluginApi" text="cloud"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 22 | 0 | 22 | 0 | | <DocLink id="kibConsolePluginApi" text="console"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 9 | 0 | 9 | 1 | -| <DocLink id="kibCorePluginApi" text="core"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2300 | 27 | 1019 | 29 | +| <DocLink id="kibCorePluginApi" text="core"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2298 | 27 | 1018 | 29 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| <DocLink id="kibCustomIntegrationsPluginApi" text="customIntegrations"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 85 | 1 | 78 | 1 | +| <DocLink id="kibCustomIntegrationsPluginApi" text="customIntegrations"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 91 | 1 | 75 | 1 | | <DocLink id="kibDashboardPluginApi" text="dashboard"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 145 | 1 | 132 | 10 | | <DocLink id="kibDashboardEnhancedPluginApi" text="dashboardEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 51 | 0 | 50 | 0 | -| <DocLink id="kibDataPluginApi" text="data"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3192 | 43 | 2807 | 48 | +| <DocLink id="kibDataPluginApi" text="data"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3193 | 43 | 2807 | 48 | | <DocLink id="kibDataEnhancedPluginApi" text="dataEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Enhanced data plugin. (See src/plugins/data.) Enhances the main data plugin with a search session management UI. Includes a reusable search session indicator component to use in other applications. Exposes routes for managing search sessions. Includes a service that monitors, updates, and cleans up search session saved objects. | 16 | 0 | 16 | 2 | -| <DocLink id="kibDataViewsPluginApi" text="dataViews"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 681 | 6 | 541 | 5 | +| <DocLink id="kibDataViewsPluginApi" text="dataViews"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 683 | 6 | 541 | 5 | | <DocLink id="kibDataVisualizerPluginApi" text="dataVisualizer"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 80 | 5 | 80 | 0 | | <DocLink id="kibDevToolsPluginApi" text="devTools"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 | -| <DocLink id="kibDiscoverPluginApi" text="discover"/> | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 82 | 0 | 56 | 6 | +| <DocLink id="kibDiscoverPluginApi" text="discover"/> | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 103 | 0 | 77 | 7 | | <DocLink id="kibDiscoverEnhancedPluginApi" text="discoverEnhanced"/> | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | <DocLink id="kibEmbeddablePluginApi" text="embeddable"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 469 | 5 | 393 | 3 | | <DocLink id="kibEmbeddableEnhancedPluginApi" text="embeddableEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | @@ -62,11 +61,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibExpressionRevealImagePluginApi" text="expressionRevealImage"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'revealImage' function and renderer to expressions | 12 | 0 | 12 | 3 | | <DocLink id="kibExpressionShapePluginApi" text="expressionShape"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 143 | 0 | 143 | 0 | | <DocLink id="kibExpressionTagcloudPluginApi" text="expressionTagcloud"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 5 | 0 | 5 | 0 | -| <DocLink id="kibExpressionsPluginApi" text="expressions"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2095 | 27 | 1646 | 4 | +| <DocLink id="kibExpressionsPluginApi" text="expressions"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2086 | 27 | 1640 | 4 | | <DocLink id="kibFeaturesPluginApi" text="features"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 216 | 0 | 98 | 2 | | <DocLink id="kibFieldFormatsPluginApi" text="fieldFormats"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 7 | 250 | 3 | | <DocLink id="kibFileUploadPluginApi" text="fileUpload"/> | [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. | 129 | 4 | 129 | 1 | -| <DocLink id="kibFleetPluginApi" text="fleet"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1207 | 15 | 1107 | 10 | +| <DocLink id="kibFleetPluginApi" text="fleet"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1210 | 15 | 1110 | 10 | | <DocLink id="kibGlobalSearchPluginApi" text="globalSearch"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -105,11 +104,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibObservabilityPluginApi" text="observability"/> | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 258 | 1 | 257 | 12 | | <DocLink id="kibOsqueryPluginApi" text="osquery"/> | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 11 | 0 | 11 | 0 | | painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| <DocLink id="kibPresentationUtilPluginApi" text="presentationUtil"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 178 | 3 | 151 | 5 | +| <DocLink id="kibPresentationUtilPluginApi" text="presentationUtil"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 178 | 3 | 151 | 6 | | <DocLink id="kibRemoteClustersPluginApi" text="remoteClusters"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 | | <DocLink id="kibReportingPluginApi" text="reporting"/> | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 135 | 0 | 134 | 12 | | <DocLink id="kibRollupPluginApi" text="rollup"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 20 | 0 | 20 | 0 | -| <DocLink id="kibRuleRegistryPluginApi" text="ruleRegistry"/> | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 132 | 0 | 109 | 7 | +| <DocLink id="kibRuleRegistryPluginApi" text="ruleRegistry"/> | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 136 | 0 | 113 | 7 | | <DocLink id="kibRuntimeFieldsPluginApi" text="runtimeFields"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 24 | 0 | 19 | 2 | | <DocLink id="kibSavedObjectsPluginApi" text="savedObjects"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 221 | 3 | 207 | 4 | | <DocLink id="kibSavedObjectsManagementPluginApi" text="savedObjectsManagement"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 103 | 0 | 90 | 0 | @@ -131,7 +130,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibTimelinesPluginApi" text="timelines"/> | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 968 | 6 | 847 | 25 | | <DocLink id="kibTransformPluginApi" text="transform"/> | [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 | -| <DocLink id="kibTriggersActionsUiPluginApi" text="triggersActionsUi"/> | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 239 | 1 | 230 | 18 | +| <DocLink id="kibTriggersActionsUiPluginApi" text="triggersActionsUi"/> | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 238 | 1 | 229 | 18 | | <DocLink id="kibUiActionsPluginApi" text="uiActions"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 127 | 0 | 88 | 11 | | <DocLink id="kibUiActionsEnhancedPluginApi" text="uiActionsEnhanced"/> | [Kibana App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 203 | 2 | 145 | 9 | | upgradeAssistant | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | @@ -153,13 +152,12 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibVisualizationsPluginApi" text="visualizations"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 304 | 13 | 286 | 16 | | <DocLink id="kibVisualizePluginApi" text="visualize"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the visualize application which includes the listing page and the app frame, which will load the visualization's editor. | 24 | 0 | 23 | 1 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| xpackLegacy | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | ## Package Directory | Package name | Maintaining team | Description | API Cnt | Any Cnt | Missing<br />comments | Missing<br />exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| <DocLink id="kibElasticApmGeneratorPluginApi" text="@elastic/apm-generator"/> | [Owner missing] | Elastic APM trace data generator | 15 | 0 | 15 | 2 | +| <DocLink id="kibElasticApmGeneratorPluginApi" text="@elastic/apm-generator"/> | [Owner missing] | Elastic APM trace data generator | 17 | 0 | 17 | 2 | | <DocLink id="kibElasticDatemathPluginApi" text="@elastic/datemath"/> | [Owner missing] | elasticsearch datemath parser, used in kibana | 44 | 0 | 43 | 0 | | <DocLink id="kibKbnAcePluginApi" text="@kbn/ace"/> | [Owner missing] | - | 11 | 5 | 11 | 0 | | <DocLink id="kibKbnAlertsPluginApi" text="@kbn/alerts"/> | [Owner missing] | Alerts components and hooks | 9 | 1 | 9 | 0 | @@ -170,7 +168,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibKbnConfigPluginApi" text="@kbn/config"/> | [Owner missing] | - | 66 | 0 | 46 | 1 | | <DocLink id="kibKbnConfigSchemaPluginApi" text="@kbn/config-schema"/> | [Owner missing] | - | 109 | 3 | 107 | 18 | | <DocLink id="kibKbnCryptoPluginApi" text="@kbn/crypto"/> | [Owner missing] | - | 13 | 0 | 7 | 0 | -| <DocLink id="kibKbnDevUtilsPluginApi" text="@kbn/dev-utils"/> | [Owner missing] | - | 258 | 7 | 231 | 4 | +| <DocLink id="kibKbnDevUtilsPluginApi" text="@kbn/dev-utils"/> | [Owner missing] | - | 280 | 6 | 214 | 0 | | <DocLink id="kibKbnDocsUtilsPluginApi" text="@kbn/docs-utils"/> | [Owner missing] | - | 1 | 0 | 1 | 0 | | <DocLink id="kibKbnEsArchiverPluginApi" text="@kbn/es-archiver"/> | [Owner missing] | - | 25 | 0 | 12 | 1 | | <DocLink id="kibKbnEsQueryPluginApi" text="@kbn/es-query"/> | [Owner missing] | - | 205 | 2 | 153 | 14 | @@ -197,7 +195,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | <DocLink id="kibKbnSecuritysolutionListHooksPluginApi" text="@kbn/securitysolution-list-hooks"/> | [Owner missing] | Security solution list ReactJS hooks | 56 | 0 | 44 | 0 | | <DocLink id="kibKbnSecuritysolutionListUtilsPluginApi" text="@kbn/securitysolution-list-utils"/> | [Owner missing] | security solution list utilities | 222 | 0 | 177 | 0 | | <DocLink id="kibKbnSecuritysolutionTGridPluginApi" text="@kbn/securitysolution-t-grid"/> | [Owner missing] | security solution t-grid packages will allow sharing components between timelines and security_solution plugin until we transfer all functionality to timelines plugin | 120 | 0 | 116 | 0 | -| <DocLink id="kibKbnSecuritysolutionUtilsPluginApi" text="@kbn/securitysolution-utils"/> | [Owner missing] | security solution utilities to use across plugins such lists, security_solution, cases, etc... | 4 | 0 | 2 | 0 | +| <DocLink id="kibKbnSecuritysolutionUtilsPluginApi" text="@kbn/securitysolution-utils"/> | [Owner missing] | security solution utilities to use across plugins such lists, security_solution, cases, etc... | 6 | 0 | 4 | 0 | | <DocLink id="kibKbnServerHttpToolsPluginApi" text="@kbn/server-http-tools"/> | [Owner missing] | - | 53 | 0 | 50 | 1 | | <DocLink id="kibKbnServerRouteRepositoryPluginApi" text="@kbn/server-route-repository"/> | [Owner missing] | - | 28 | 0 | 27 | 1 | | <DocLink id="kibKbnStdPluginApi" text="@kbn/std"/> | [Owner missing] | - | 96 | 1 | 63 | 2 | diff --git a/api_docs/presentation_util.json b/api_docs/presentation_util.json index ecec195628cf6..50a4540b3af40 100644 --- a/api_docs/presentation_util.json +++ b/api_docs/presentation_util.json @@ -1238,7 +1238,7 @@ "label": "SolutionToolbarPopover", "description": [], "signature": [ - "({ label, iconType, primary, iconSide, ...popover }: ", + "({ label, iconType, primary, iconSide, children, ...popover }: ", "Props", ") => JSX.Element" ], @@ -1250,7 +1250,7 @@ "id": "def-public.SolutionToolbarPopover.$1", "type": "CompoundType", "tags": [], - "label": "{\n label,\n iconType,\n primary,\n iconSide,\n ...popover\n}", + "label": "{\n label,\n iconType,\n primary,\n iconSide,\n children,\n ...popover\n}", "description": [], "signature": [ "Props" @@ -1870,19 +1870,6 @@ "deprecated": false, "children": [], "returnComment": [] - }, - { - "parentPluginId": "presentationUtil", - "id": "def-public.QuickButtonProps.isDarkModeEnabled", - "type": "CompoundType", - "tags": [], - "label": "isDarkModeEnabled", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.tsx", - "deprecated": false } ], "initialIsOpen": false @@ -2402,6 +2389,19 @@ ], "path": "src/plugins/presentation_util/public/types.ts", "deprecated": false + }, + { + "parentPluginId": "presentationUtil", + "id": "def-public.PresentationUtilPluginStart.controlsService", + "type": "Object", + "tags": [], + "label": "controlsService", + "description": [], + "signature": [ + "PresentationControlsService" + ], + "path": "src/plugins/presentation_util/public/types.ts", + "deprecated": false } ], "lifecycle": "start", diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 4c31547582b17..9ff91703a0916 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -18,7 +18,7 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 178 | 3 | 151 | 5 | +| 178 | 3 | 151 | 6 | ## Client diff --git a/api_docs/reporting.json b/api_docs/reporting.json index 8843a7ed21b92..4296dfad34b3f 100644 --- a/api_docs/reporting.json +++ b/api_docs/reporting.json @@ -925,7 +925,7 @@ "section": "def-server.PluginInitializerContext", "text": "PluginInitializerContext" }, - "<Readonly<{ encryptionKey?: string | undefined; } & { enabled: boolean; capture: Readonly<{} & { browser: Readonly<{} & { type: string; chromium: Readonly<{ inspect?: boolean | undefined; disableSandbox?: boolean | undefined; } & { proxy: Readonly<{ server?: string | undefined; bypass?: string[] | undefined; } & { enabled: boolean; }>; }>; autoDownload: boolean; }>; zoom: number; timeouts: Readonly<{} & { openUrl: number | moment.Duration; waitForElements: number | moment.Duration; renderComplete: number | moment.Duration; }>; networkPolicy: Readonly<{} & { enabled: boolean; rules: Readonly<{ host?: string | undefined; protocol?: string | undefined; } & { allow: boolean; }>[]; }>; viewport: Readonly<{} & { height: number; width: number; }>; loadDelay: number | moment.Duration; maxAttempts: number; }>; roles: Readonly<{} & { enabled: boolean; allow: string[]; }>; kibanaServer: Readonly<{ hostname?: string | undefined; port?: number | undefined; protocol?: string | undefined; } & {}>; queue: Readonly<{} & { timeout: number | moment.Duration; pollInterval: number | moment.Duration; indexInterval: string; pollEnabled: boolean; pollIntervalErrorMultiplier: number; }>; csv: Readonly<{} & { scroll: Readonly<{} & { size: number; duration: string; }>; checkForFormulas: boolean; escapeFormulaValues: boolean; enablePanelActionDownload: boolean; maxSizeBytes: number | ", + "<Readonly<{ encryptionKey?: string | undefined; } & { enabled: boolean; capture: Readonly<{} & { browser: Readonly<{} & { type: string; chromium: Readonly<{ inspect?: boolean | undefined; disableSandbox?: boolean | undefined; } & { proxy: Readonly<{ server?: string | undefined; bypass?: string[] | undefined; } & { enabled: boolean; }>; }>; autoDownload: boolean; }>; zoom: number; timeouts: Readonly<{} & { openUrl: number | moment.Duration; waitForElements: number | moment.Duration; renderComplete: number | moment.Duration; }>; networkPolicy: Readonly<{} & { enabled: boolean; rules: Readonly<{ host?: string | undefined; protocol?: string | undefined; } & { allow: boolean; }>[]; }>; loadDelay: number | moment.Duration; maxAttempts: number; }>; roles: Readonly<{} & { enabled: boolean; allow: string[]; }>; kibanaServer: Readonly<{ hostname?: string | undefined; port?: number | undefined; protocol?: string | undefined; } & {}>; queue: Readonly<{} & { timeout: number | moment.Duration; pollInterval: number | moment.Duration; indexInterval: string; pollEnabled: boolean; pollIntervalErrorMultiplier: number; }>; csv: Readonly<{} & { scroll: Readonly<{} & { size: number; duration: string; }>; checkForFormulas: boolean; escapeFormulaValues: boolean; enablePanelActionDownload: boolean; maxSizeBytes: number | ", { "pluginId": "@kbn/config-schema", "scope": "server", @@ -1323,7 +1323,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Promise<", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">) => Promise<", { "pluginId": "core", "scope": "server", @@ -1352,7 +1352,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">" ], "path": "x-pack/plugins/reporting/server/core.ts", "deprecated": false, @@ -1771,7 +1771,7 @@ "section": "def-server.PluginInitializerContext", "text": "PluginInitializerContext" }, - "<Readonly<{ encryptionKey?: string | undefined; } & { enabled: boolean; capture: Readonly<{} & { browser: Readonly<{} & { type: string; chromium: Readonly<{ inspect?: boolean | undefined; disableSandbox?: boolean | undefined; } & { proxy: Readonly<{ server?: string | undefined; bypass?: string[] | undefined; } & { enabled: boolean; }>; }>; autoDownload: boolean; }>; zoom: number; timeouts: Readonly<{} & { openUrl: number | moment.Duration; waitForElements: number | moment.Duration; renderComplete: number | moment.Duration; }>; networkPolicy: Readonly<{} & { enabled: boolean; rules: Readonly<{ host?: string | undefined; protocol?: string | undefined; } & { allow: boolean; }>[]; }>; viewport: Readonly<{} & { height: number; width: number; }>; loadDelay: number | moment.Duration; maxAttempts: number; }>; roles: Readonly<{} & { enabled: boolean; allow: string[]; }>; kibanaServer: Readonly<{ hostname?: string | undefined; port?: number | undefined; protocol?: string | undefined; } & {}>; queue: Readonly<{} & { timeout: number | moment.Duration; pollInterval: number | moment.Duration; indexInterval: string; pollEnabled: boolean; pollIntervalErrorMultiplier: number; }>; csv: Readonly<{} & { scroll: Readonly<{} & { size: number; duration: string; }>; checkForFormulas: boolean; escapeFormulaValues: boolean; enablePanelActionDownload: boolean; maxSizeBytes: number | ", + "<Readonly<{ encryptionKey?: string | undefined; } & { enabled: boolean; capture: Readonly<{} & { browser: Readonly<{} & { type: string; chromium: Readonly<{ inspect?: boolean | undefined; disableSandbox?: boolean | undefined; } & { proxy: Readonly<{ server?: string | undefined; bypass?: string[] | undefined; } & { enabled: boolean; }>; }>; autoDownload: boolean; }>; zoom: number; timeouts: Readonly<{} & { openUrl: number | moment.Duration; waitForElements: number | moment.Duration; renderComplete: number | moment.Duration; }>; networkPolicy: Readonly<{} & { enabled: boolean; rules: Readonly<{ host?: string | undefined; protocol?: string | undefined; } & { allow: boolean; }>[]; }>; loadDelay: number | moment.Duration; maxAttempts: number; }>; roles: Readonly<{} & { enabled: boolean; allow: string[]; }>; kibanaServer: Readonly<{ hostname?: string | undefined; port?: number | undefined; protocol?: string | undefined; } & {}>; queue: Readonly<{} & { timeout: number | moment.Duration; pollInterval: number | moment.Duration; indexInterval: string; pollEnabled: boolean; pollIntervalErrorMultiplier: number; }>; csv: Readonly<{} & { scroll: Readonly<{} & { size: number; duration: string; }>; checkForFormulas: boolean; escapeFormulaValues: boolean; enablePanelActionDownload: boolean; maxSizeBytes: number | ", { "pluginId": "@kbn/config-schema", "scope": "server", @@ -1968,7 +1968,7 @@ "section": "def-server.ReportingConfig", "text": "ReportingConfig" }, - " extends Config<Readonly<{ encryptionKey?: string | undefined; } & { enabled: boolean; capture: Readonly<{} & { browser: Readonly<{} & { type: string; chromium: Readonly<{ inspect?: boolean | undefined; disableSandbox?: boolean | undefined; } & { proxy: Readonly<{ server?: string | undefined; bypass?: string[] | undefined; } & { enabled: boolean; }>; }>; autoDownload: boolean; }>; zoom: number; timeouts: Readonly<{} & { openUrl: number | moment.Duration; waitForElements: number | moment.Duration; renderComplete: number | moment.Duration; }>; networkPolicy: Readonly<{} & { enabled: boolean; rules: Readonly<{ host?: string | undefined; protocol?: string | undefined; } & { allow: boolean; }>[]; }>; viewport: Readonly<{} & { height: number; width: number; }>; loadDelay: number | moment.Duration; maxAttempts: number; }>; roles: Readonly<{} & { enabled: boolean; allow: string[]; }>; kibanaServer: Readonly<{ hostname?: string | undefined; port?: number | undefined; protocol?: string | undefined; } & {}>; queue: Readonly<{} & { timeout: number | moment.Duration; pollInterval: number | moment.Duration; indexInterval: string; pollEnabled: boolean; pollIntervalErrorMultiplier: number; }>; csv: Readonly<{} & { scroll: Readonly<{} & { size: number; duration: string; }>; checkForFormulas: boolean; escapeFormulaValues: boolean; enablePanelActionDownload: boolean; maxSizeBytes: number | ", + " extends Config<Readonly<{ encryptionKey?: string | undefined; } & { enabled: boolean; capture: Readonly<{} & { browser: Readonly<{} & { type: string; chromium: Readonly<{ inspect?: boolean | undefined; disableSandbox?: boolean | undefined; } & { proxy: Readonly<{ server?: string | undefined; bypass?: string[] | undefined; } & { enabled: boolean; }>; }>; autoDownload: boolean; }>; zoom: number; timeouts: Readonly<{} & { openUrl: number | moment.Duration; waitForElements: number | moment.Duration; renderComplete: number | moment.Duration; }>; networkPolicy: Readonly<{} & { enabled: boolean; rules: Readonly<{ host?: string | undefined; protocol?: string | undefined; } & { allow: boolean; }>[]; }>; loadDelay: number | moment.Duration; maxAttempts: number; }>; roles: Readonly<{} & { enabled: boolean; allow: string[]; }>; kibanaServer: Readonly<{ hostname?: string | undefined; port?: number | undefined; protocol?: string | undefined; } & {}>; queue: Readonly<{} & { timeout: number | moment.Duration; pollInterval: number | moment.Duration; indexInterval: string; pollEnabled: boolean; pollIntervalErrorMultiplier: number; }>; csv: Readonly<{} & { scroll: Readonly<{} & { size: number; duration: string; }>; checkForFormulas: boolean; escapeFormulaValues: boolean; enablePanelActionDownload: boolean; maxSizeBytes: number | ", { "pluginId": "@kbn/config-schema", "scope": "server", @@ -2187,7 +2187,7 @@ "TaskScheduling", ", \"schedule\" | \"runNow\" | \"ephemeralRunNow\" | \"ensureScheduled\"> & Pick<", "TaskStore", - ", \"remove\" | \"get\" | \"fetch\"> & { removeIfExists: (id: string) => Promise<void>; } & { supportsEphemeralTasks: () => boolean; }" + ", \"remove\" | \"fetch\" | \"get\"> & { removeIfExists: (id: string) => Promise<void>; } & { supportsEphemeralTasks: () => boolean; }" ], "path": "x-pack/plugins/reporting/server/types.ts", "deprecated": false diff --git a/api_docs/rule_registry.json b/api_docs/rule_registry.json index 2d9e79f727c0e..89c359461c72f 100644 --- a/api_docs/rule_registry.json +++ b/api_docs/rule_registry.json @@ -878,6 +878,87 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriterInitializationError", + "type": "Class", + "tags": [], + "label": "RuleDataWriterInitializationError", + "description": [], + "signature": [ + { + "pluginId": "ruleRegistry", + "scope": "server", + "docId": "kibRuleRegistryPluginApi", + "section": "def-server.RuleDataWriterInitializationError", + "text": "RuleDataWriterInitializationError" + }, + " extends Error" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriterInitializationError.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriterInitializationError.Unnamed.$1", + "type": "CompoundType", + "tags": [], + "label": "resourceType", + "description": [], + "signature": [ + "\"index\" | \"namespace\"" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriterInitializationError.Unnamed.$2", + "type": "string", + "tags": [], + "label": "registrationContext", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriterInitializationError.Unnamed.$3", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "string | Error" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false } ], "functions": [ @@ -1085,10 +1166,10 @@ }, { "parentPluginId": "ruleRegistry", - "id": "def-server.createPersistenceRuleTypeFactory", + "id": "def-server.createPersistenceRuleTypeWrapper", "type": "Function", "tags": [], - "label": "createPersistenceRuleTypeFactory", + "label": "createPersistenceRuleTypeWrapper", "description": [], "signature": [ "({ logger, ruleDataClient }: { ruleDataClient: ", @@ -1107,23 +1188,15 @@ "section": "def-server.Logger", "text": "Logger" }, - "; }) => <TState extends Record<string, unknown>, TParams extends Record<string, unknown>, TServices extends ", + "; }) => <TParams extends Record<string, unknown>, TState extends Record<string, unknown>, TInstanceContext extends { [x: string]: unknown; } = {}, TActionGroupIds extends string = never>(type: ", { "pluginId": "ruleRegistry", "scope": "server", "docId": "kibRuleRegistryPluginApi", - "section": "def-server.PersistenceServices", - "text": "PersistenceServices" + "section": "def-server.PersistenceAlertType", + "text": "PersistenceAlertType" }, - "<TAlertInstanceContext>, TAlertInstanceContext extends { [x: string]: unknown; } = {}>(type: ", - { - "pluginId": "ruleRegistry", - "scope": "server", - "docId": "kibRuleRegistryPluginApi", - "section": "def-server.AlertTypeWithExecutor", - "text": "AlertTypeWithExecutor" - }, - "<TState, TParams, TAlertInstanceContext, TServices>) => { executor: (options: ", + "<TParams, TState, TInstanceContext, TActionGroupIds>) => { executor: (options: ", { "pluginId": "alerting", "scope": "server", @@ -1131,7 +1204,15 @@ "section": "def-server.AlertExecutorOptions", "text": "AlertExecutorOptions" }, - "<TParams, TState, { [x: string]: unknown; }, TAlertInstanceContext, never> & { services: TServices; }) => Promise<void | TState>; id: string; name: string; validate?: { params?: ", + "<TParams, TState, { [x: string]: unknown; }, TInstanceContext, ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.WithoutReservedActionGroups", + "text": "WithoutReservedActionGroups" + }, + "<TActionGroupIds, never>>) => Promise<void | TState>; id: string; name: string; validate?: { params?: ", "AlertTypeParamsValidator", "<TParams> | undefined; } | undefined; actionGroups: ", { @@ -1141,7 +1222,7 @@ "section": "def-common.ActionGroup", "text": "ActionGroup" }, - "<string>[]; defaultActionGroupId: string; recoveryActionGroup?: ", + "<TActionGroupIds>[]; defaultActionGroupId: TActionGroupIds; recoveryActionGroup?: ", { "pluginId": "alerting", "scope": "common", @@ -1149,7 +1230,7 @@ "section": "def-common.ActionGroup", "text": "ActionGroup" }, - "<string> | undefined; producer: string; actionVariables?: { context?: ", + "<never> | undefined; producer: string; actionVariables?: { context?: ", { "pluginId": "alerting", "scope": "common", @@ -1183,14 +1264,14 @@ }, "<TParams>; injectReferences: (params: TParams, references: ", "SavedObjectReference", - "[]) => TParams; } | undefined; isExportable: boolean; ruleTaskTimeout?: string | undefined; }" + "[]) => TParams; } | undefined; isExportable: boolean; defaultScheduleInterval?: string | undefined; minimumScheduleInterval?: string | undefined; ruleTaskTimeout?: string | undefined; }" ], - "path": "x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_factory.ts", + "path": "x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts", "deprecated": false, "children": [ { "parentPluginId": "ruleRegistry", - "id": "def-server.createPersistenceRuleTypeFactory.$1", + "id": "def-server.createPersistenceRuleTypeWrapper.$1", "type": "Object", "tags": [], "label": "{ logger, ruleDataClient }", @@ -1214,7 +1295,7 @@ }, "; }" ], - "path": "x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_factory.ts", + "path": "x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts", "deprecated": false, "isRequired": true } @@ -1725,7 +1806,7 @@ "ApiResponse", "<", "BulkResponse", - ", unknown>>" + ", unknown> | undefined>" ], "path": "x-pack/plugins/rule_registry/server/rule_data_client/types.ts", "deprecated": false, @@ -1812,16 +1893,6 @@ "tags": [], "label": "PersistenceServices", "description": [], - "signature": [ - { - "pluginId": "ruleRegistry", - "scope": "server", - "docId": "kibRuleRegistryPluginApi", - "section": "def-server.PersistenceServices", - "text": "PersistenceServices" - }, - "<TAlertInstanceContext>" - ], "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", "deprecated": false, "children": [ @@ -1839,7 +1910,7 @@ "ApiResponse", "<", "BulkResponse", - ", unknown>>" + ", unknown> | undefined>" ], "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", "deprecated": false, @@ -1945,7 +2016,7 @@ "section": "def-server.AlertType", "text": "AlertType" }, - "<TParams, TParams, TState, { [x: string]: unknown; }, TAlertInstanceContext, string, string>, \"id\" | \"name\" | \"validate\" | \"actionGroups\" | \"defaultActionGroupId\" | \"recoveryActionGroup\" | \"producer\" | \"actionVariables\" | \"minimumLicenseRequired\" | \"useSavedObjectReferences\" | \"isExportable\" | \"ruleTaskTimeout\"> & { executor: ", + "<TParams, TParams, TState, { [x: string]: unknown; }, TAlertInstanceContext, string, string>, \"id\" | \"name\" | \"validate\" | \"actionGroups\" | \"defaultActionGroupId\" | \"recoveryActionGroup\" | \"producer\" | \"actionVariables\" | \"minimumLicenseRequired\" | \"useSavedObjectReferences\" | \"isExportable\" | \"defaultScheduleInterval\" | \"minimumScheduleInterval\" | \"ruleTaskTimeout\"> & { executor: ", "AlertTypeExecutor", "<TState, TParams, TAlertInstanceContext, TServices>; }" ], @@ -1955,10 +2026,10 @@ }, { "parentPluginId": "ruleRegistry", - "id": "def-server.CreatePersistenceRuleTypeFactory", + "id": "def-server.CreatePersistenceRuleTypeWrapper", "type": "Type", "tags": [], - "label": "CreatePersistenceRuleTypeFactory", + "label": "CreatePersistenceRuleTypeWrapper", "description": [], "signature": [ "(options: { ruleDataClient: ", @@ -1977,31 +2048,23 @@ "section": "def-server.Logger", "text": "Logger" }, - "; }) => <TState extends Record<string, unknown>, TParams extends Record<string, unknown>, TServices extends ", - { - "pluginId": "ruleRegistry", - "scope": "server", - "docId": "kibRuleRegistryPluginApi", - "section": "def-server.PersistenceServices", - "text": "PersistenceServices" - }, - "<TAlertInstanceContext>, TAlertInstanceContext extends { [x: string]: unknown; } = {}>(type: ", + "; }) => <TParams extends Record<string, unknown>, TState extends Record<string, unknown>, TInstanceContext extends { [x: string]: unknown; } = {}, TActionGroupIds extends string = never>(type: ", { "pluginId": "ruleRegistry", "scope": "server", "docId": "kibRuleRegistryPluginApi", - "section": "def-server.AlertTypeWithExecutor", - "text": "AlertTypeWithExecutor" + "section": "def-server.PersistenceAlertType", + "text": "PersistenceAlertType" }, - "<TState, TParams, TAlertInstanceContext, TServices>) => ", + "<TParams, TState, TInstanceContext, TActionGroupIds>) => ", { - "pluginId": "ruleRegistry", + "pluginId": "alerting", "scope": "server", - "docId": "kibRuleRegistryPluginApi", - "section": "def-server.AlertTypeWithExecutor", - "text": "AlertTypeWithExecutor" + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertType", + "text": "AlertType" }, - "<TState, TParams, TAlertInstanceContext, TServices>" + "<TParams, TParams, TState, { [x: string]: unknown; }, TInstanceContext, TActionGroupIds, never>" ], "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", "deprecated": false, @@ -2009,7 +2072,7 @@ "children": [ { "parentPluginId": "ruleRegistry", - "id": "def-server.CreatePersistenceRuleTypeFactory.$1", + "id": "def-server.CreatePersistenceRuleTypeWrapper.$1", "type": "Object", "tags": [], "label": "options", @@ -2209,38 +2272,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "ruleRegistry", - "id": "def-server.PersistenceAlertQueryService", - "type": "Type", - "tags": [], - "label": "PersistenceAlertQueryService", - "description": [], - "signature": [ - "(query: ", - "SearchRequest", - ") => Promise<Record<string, unknown>[]>" - ], - "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "ruleRegistry", - "id": "def-server.PersistenceAlertQueryService.$1", - "type": "Object", - "tags": [], - "label": "query", - "description": [], - "signature": [ - "SearchRequest" - ], - "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "ruleRegistry", "id": "def-server.PersistenceAlertService", @@ -2255,7 +2286,7 @@ "ApiResponse", "<", "BulkResponse", - ", unknown>>" + ", unknown> | undefined>" ], "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", "deprecated": false, @@ -2290,6 +2321,52 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "ruleRegistry", + "id": "def-server.PersistenceAlertType", + "type": "Type", + "tags": [], + "label": "PersistenceAlertType", + "description": [], + "signature": [ + "Pick<", + { + "pluginId": "alerting", + "scope": "server", + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertType", + "text": "AlertType" + }, + "<TParams, TParams, TState, { [x: string]: unknown; }, TInstanceContext, TActionGroupIds, never>, \"id\" | \"name\" | \"validate\" | \"actionGroups\" | \"defaultActionGroupId\" | \"recoveryActionGroup\" | \"producer\" | \"actionVariables\" | \"minimumLicenseRequired\" | \"useSavedObjectReferences\" | \"isExportable\" | \"defaultScheduleInterval\" | \"minimumScheduleInterval\" | \"ruleTaskTimeout\"> & { executor: (options: ", + { + "pluginId": "alerting", + "scope": "server", + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertExecutorOptions", + "text": "AlertExecutorOptions" + }, + "<TParams, TState, { [x: string]: unknown; }, TInstanceContext, ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.WithoutReservedActionGroups", + "text": "WithoutReservedActionGroups" + }, + "<TActionGroupIds, never>> & { services: ", + { + "pluginId": "ruleRegistry", + "scope": "server", + "docId": "kibRuleRegistryPluginApi", + "section": "def-server.PersistenceServices", + "text": "PersistenceServices" + }, + "; }) => Promise<void | TState>; }" + ], + "path": "x-pack/plugins/rule_registry/server/utils/persistence_types.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "ruleRegistry", "id": "def-server.RuleRegistryPluginConfig", diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 5bd8aeff7d1b2..7e05924fca263 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -18,7 +18,7 @@ Contact [RAC](https://github.com/orgs/elastic/teams/rac) for questions regarding | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 132 | 0 | 109 | 7 | +| 136 | 0 | 113 | 7 | ## Server diff --git a/api_docs/runtime_fields.json b/api_docs/runtime_fields.json index 83618b64aca36..e89ac78622778 100644 --- a/api_docs/runtime_fields.json +++ b/api_docs/runtime_fields.json @@ -330,7 +330,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"long\" | \"double\"" + "\"boolean\" | \"keyword\" | \"date\" | \"ip\" | \"long\" | \"double\"" ], "path": "x-pack/plugins/runtime_fields/public/types.ts", "deprecated": false @@ -363,7 +363,7 @@ "description": [], "signature": [ "ComboBoxOption", - "<\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"long\" | \"double\">[]" + "<\"boolean\" | \"keyword\" | \"date\" | \"ip\" | \"long\" | \"double\">[]" ], "path": "x-pack/plugins/runtime_fields/public/constants.ts", "deprecated": false, @@ -377,7 +377,7 @@ "label": "RuntimeType", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"long\" | \"double\"" + "\"boolean\" | \"keyword\" | \"date\" | \"ip\" | \"long\" | \"double\"" ], "path": "x-pack/plugins/runtime_fields/public/types.ts", "deprecated": false, diff --git a/api_docs/saved_objects.json b/api_docs/saved_objects.json index af63ad120a8c0..9cb53a0ada85b 100644 --- a/api_docs/saved_objects.json +++ b/api_docs/saved_objects.json @@ -562,11 +562,11 @@ "references": [ { "plugin": "discover", - "path": "src/plugins/discover/public/saved_searches/saved_searches.ts" + "path": "src/plugins/discover/public/saved_searches/legacy/saved_searches.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/saved_searches/saved_searches.ts" + "path": "src/plugins/discover/public/saved_searches/legacy/saved_searches.ts" }, { "plugin": "discover", @@ -596,14 +596,6 @@ "plugin": "visualizations", "path": "src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts" }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/services.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/services.ts" - }, { "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/saved_objects.ts" @@ -734,7 +726,7 @@ "section": "def-public.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"bulkUpdate\">" + ", \"create\" | \"bulkCreate\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"bulkUpdate\">" ], "path": "src/plugins/saved_objects/public/saved_object/saved_object_loader.ts", "deprecated": false, @@ -1487,7 +1479,7 @@ "section": "def-public.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"bulkUpdate\">; overlays: ", + ", \"create\" | \"bulkCreate\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"bulkUpdate\">; overlays: ", { "pluginId": "core", "scope": "public", @@ -1613,17 +1605,7 @@ "label": "savedObjectsClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string) => Promise<", - { - "pluginId": "core", - "scope": "public", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-public.SimpleSavedObject", - "text": "SimpleSavedObject" - }, - "<T>>; delete: (type: string, id: string, options?: ", - "SavedObjectsDeleteOptions", - " | undefined) => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "public", @@ -1663,7 +1645,9 @@ "section": "def-public.SavedObjectsBatchResponse", "text": "SavedObjectsBatchResponse" }, - "<unknown>>; find: <T = unknown, A = unknown>(options: Pick<", + "<unknown>>; delete: (type: string, id: string, options?: ", + "SavedObjectsDeleteOptions", + " | undefined) => Promise<{}>; find: <T = unknown, A = unknown>(options: Pick<", { "pluginId": "core", "scope": "server", @@ -1695,7 +1679,15 @@ "section": "def-public.ResolvedSimpleSavedObject", "text": "ResolvedSimpleSavedObject" }, - "<T>[]; }>; resolve: <T = unknown>(type: string, id: string) => Promise<", + "<T>[]; }>; get: <T = unknown>(type: string, id: string) => Promise<", + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-public.SimpleSavedObject", + "text": "SimpleSavedObject" + }, + "<T>>; resolve: <T = unknown>(type: string, id: string) => Promise<", { "pluginId": "core", "scope": "public", @@ -2094,29 +2086,17 @@ "path": "src/plugins/saved_objects/public/types.ts", "deprecated": true, "references": [ - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" - }, { "plugin": "savedObjectsTaggingOss", "path": "src/plugins/saved_objects_tagging_oss/public/api.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/saved_searches/_saved_search.ts" + "path": "src/plugins/discover/public/saved_searches/legacy/_saved_search.ts" }, { "plugin": "discover", - "path": "src/plugins/discover/public/saved_searches/_saved_search.ts" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" - }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/apps/main/discover_main_route.tsx" + "path": "src/plugins/discover/public/saved_searches/legacy/_saved_search.ts" }, { "plugin": "visualizations", @@ -2181,98 +2161,6 @@ { "plugin": "dashboard", "path": "src/plugins/dashboard/public/application/actions/clone_panel_action.tsx" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/public/application/types.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/public/application/types.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/public/application/types.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/public/application/types.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/public/application/utils/get_visualization_instance.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/public/application/utils/get_visualization_instance.ts" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/types.d.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/types.d.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/types.d.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/types.d.ts" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar.d.ts" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar.d.ts" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar_title.d.ts" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar_title.d.ts" - }, - { - "plugin": "visDefaultEditor", - "path": "src/plugins/vis_default_editor/target/types/public/components/sidebar/sidebar_title.d.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/utils/get_visualization_instance.d.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/utils/get_visualization_instance.d.ts" - }, - { - "plugin": "visualize", - "path": "src/plugins/visualize/target/types/public/application/utils/get_visualization_instance.d.ts" } ], "children": [ @@ -3819,7 +3707,7 @@ "references": [ { "plugin": "discover", - "path": "src/plugins/discover/public/saved_searches/_saved_search.ts" + "path": "src/plugins/discover/public/saved_searches/legacy/_saved_search.ts" }, { "plugin": "visualizations", diff --git a/api_docs/saved_objects_management.json b/api_docs/saved_objects_management.json index e06c7faada71f..72f9ca569cc59 100644 --- a/api_docs/saved_objects_management.json +++ b/api_docs/saved_objects_management.json @@ -819,7 +819,7 @@ "label": "euiColumn", "description": [], "signature": [ - "{ children?: React.ReactNode; headers?: string | undefined; onClick?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onChange?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; color?: string | undefined; onKeyDown?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; id?: string | undefined; title?: string | undefined; description?: string | undefined; security?: string | undefined; name: React.ReactNode; field: string; defaultChecked?: boolean | undefined; defaultValue?: string | number | string[] | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; className?: string | undefined; contentEditable?: boolean | \"true\" | \"false\" | \"inherit\" | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: boolean | \"true\" | \"false\" | undefined; hidden?: boolean | undefined; lang?: string | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: boolean | \"true\" | \"false\" | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"yes\" | \"no\" | undefined; radioGroup?: string | undefined; role?: string | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"search\" | \"email\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: boolean | \"true\" | \"false\" | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: boolean | \"true\" | \"false\" | undefined; 'aria-checked'?: boolean | \"mixed\" | \"true\" | \"false\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"page\" | \"time\" | \"true\" | \"false\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: boolean | \"true\" | \"false\" | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: boolean | \"true\" | \"false\" | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: boolean | \"true\" | \"false\" | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"true\" | \"false\" | \"listbox\" | \"tree\" | \"dialog\" | undefined; 'aria-hidden'?: boolean | \"true\" | \"false\" | undefined; 'aria-invalid'?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiline'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiselectable'?: boolean | \"true\" | \"false\" | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"true\" | \"false\" | undefined; 'aria-readonly'?: boolean | \"true\" | \"false\" | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions text\" | \"removals\" | undefined; 'aria-required'?: boolean | \"true\" | \"false\" | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: boolean | \"true\" | \"false\" | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"ascending\" | \"descending\" | \"other\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCopyCapture?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCut?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCutCapture?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onPaste?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onPasteCapture?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionEnd?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionEndCapture?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionStart?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionStartCapture?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionUpdate?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionUpdateCapture?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onFocus?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onFocusCapture?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onBlur?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onBlurCapture?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onChangeCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onBeforeInput?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onBeforeInputCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInput?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInputCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onReset?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onResetCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onSubmit?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onSubmitCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInvalid?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInvalidCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onLoad?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onError?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onErrorCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onKeyDownCapture?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyPress?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyPressCapture?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyUp?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyUpCapture?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onAbort?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onAbortCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlay?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlayCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlayThrough?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlayThroughCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onDurationChange?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onDurationChangeCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEmptied?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEmptiedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEncrypted?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEncryptedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEnded?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEndedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedData?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedDataCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedMetadata?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedMetadataCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadStart?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadStartCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPause?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPauseCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlay?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlayCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlaying?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlayingCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onProgress?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onProgressCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onRateChange?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onRateChangeCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeeked?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeekedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeeking?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeekingCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onStalled?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onStalledCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSuspend?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSuspendCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onTimeUpdate?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onTimeUpdateCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onVolumeChange?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onVolumeChangeCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onWaiting?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onWaitingCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onAuxClick?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onAuxClickCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onClickCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onContextMenu?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onContextMenuCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onDoubleClick?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onDoubleClickCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onDrag?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEnd?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEndCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEnter?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEnterCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragExit?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragExitCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragLeave?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragLeaveCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragOver?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragOverCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragStart?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragStartCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDrop?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDropCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onMouseDown?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseDownCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseEnter?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseLeave?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseMove?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseMoveCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOut?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOutCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOver?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOverCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseUp?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseUpCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onSelect?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSelectCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onTouchCancel?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchCancelCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchEnd?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchEndCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchMove?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchMoveCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchStart?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchStartCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerDown?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerDownCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerMove?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerMoveCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerUp?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerUpCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerCancel?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerCancelCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerEnter?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerEnterCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerLeave?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerLeaveCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOver?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOverCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOut?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOutCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onGotPointerCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onGotPointerCaptureCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onLostPointerCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onLostPointerCaptureCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onScroll?: ((event: React.UIEvent<HTMLTableDataCellElement, UIEvent>) => void) | undefined; onScrollCapture?: ((event: React.UIEvent<HTMLTableDataCellElement, UIEvent>) => void) | undefined; onWheel?: ((event: React.WheelEvent<HTMLTableDataCellElement>) => void) | undefined; onWheelCapture?: ((event: React.WheelEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationStart?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationStartCapture?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationEnd?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationEndCapture?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationIteration?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationIterationCapture?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onTransitionEnd?: ((event: React.TransitionEvent<HTMLTableDataCellElement>) => void) | undefined; onTransitionEndCapture?: ((event: React.TransitionEvent<HTMLTableDataCellElement>) => void) | undefined; 'data-test-subj'?: string | undefined; width?: string | undefined; readOnly?: boolean | undefined; render?: ((value: any, record: ", + "{ children?: React.ReactNode; onClick?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onChange?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; color?: string | undefined; onKeyDown?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; id?: string | undefined; title?: string | undefined; description?: string | undefined; security?: string | undefined; name: React.ReactNode; field: string; defaultChecked?: boolean | undefined; defaultValue?: string | number | string[] | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; className?: string | undefined; contentEditable?: boolean | \"true\" | \"false\" | \"inherit\" | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: boolean | \"true\" | \"false\" | undefined; hidden?: boolean | undefined; lang?: string | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: boolean | \"true\" | \"false\" | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"yes\" | \"no\" | undefined; radioGroup?: string | undefined; role?: string | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"search\" | \"email\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: boolean | \"true\" | \"false\" | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: boolean | \"true\" | \"false\" | undefined; 'aria-checked'?: boolean | \"mixed\" | \"true\" | \"false\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"page\" | \"time\" | \"true\" | \"false\" | \"step\" | \"location\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: boolean | \"true\" | \"false\" | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: boolean | \"true\" | \"false\" | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: boolean | \"true\" | \"false\" | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"true\" | \"false\" | \"listbox\" | \"tree\" | \"dialog\" | undefined; 'aria-hidden'?: boolean | \"true\" | \"false\" | undefined; 'aria-invalid'?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiline'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiselectable'?: boolean | \"true\" | \"false\" | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"true\" | \"false\" | undefined; 'aria-readonly'?: boolean | \"true\" | \"false\" | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions text\" | \"removals\" | undefined; 'aria-required'?: boolean | \"true\" | \"false\" | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: boolean | \"true\" | \"false\" | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCopyCapture?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCut?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCutCapture?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onPaste?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onPasteCapture?: ((event: React.ClipboardEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionEnd?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionEndCapture?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionStart?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionStartCapture?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionUpdate?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onCompositionUpdateCapture?: ((event: React.CompositionEvent<HTMLTableDataCellElement>) => void) | undefined; onFocus?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onFocusCapture?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onBlur?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onBlurCapture?: ((event: React.FocusEvent<HTMLTableDataCellElement>) => void) | undefined; onChangeCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onBeforeInput?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onBeforeInputCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInput?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInputCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onReset?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onResetCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onSubmit?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onSubmitCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInvalid?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onInvalidCapture?: ((event: React.FormEvent<HTMLTableDataCellElement>) => void) | undefined; onLoad?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onError?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onErrorCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onKeyDownCapture?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyPress?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyPressCapture?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyUp?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onKeyUpCapture?: ((event: React.KeyboardEvent<HTMLTableDataCellElement>) => void) | undefined; onAbort?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onAbortCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlay?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlayCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlayThrough?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onCanPlayThroughCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onDurationChange?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onDurationChangeCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEmptied?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEmptiedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEncrypted?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEncryptedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEnded?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onEndedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedData?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedDataCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedMetadata?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadedMetadataCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadStart?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onLoadStartCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPause?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPauseCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlay?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlayCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlaying?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onPlayingCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onProgress?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onProgressCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onRateChange?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onRateChangeCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeeked?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeekedCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeeking?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSeekingCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onStalled?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onStalledCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSuspend?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSuspendCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onTimeUpdate?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onTimeUpdateCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onVolumeChange?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onVolumeChangeCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onWaiting?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onWaitingCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onAuxClick?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onAuxClickCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onClickCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onContextMenu?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onContextMenuCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onDoubleClick?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onDoubleClickCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onDrag?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEnd?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEndCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEnter?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragEnterCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragExit?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragExitCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragLeave?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragLeaveCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragOver?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragOverCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragStart?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDragStartCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDrop?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onDropCapture?: ((event: React.DragEvent<HTMLTableDataCellElement>) => void) | undefined; onMouseDown?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseDownCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseEnter?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseLeave?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseMove?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseMoveCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOut?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOutCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOver?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseOverCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseUp?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onMouseUpCapture?: ((event: React.MouseEvent<HTMLTableDataCellElement, MouseEvent>) => void) | undefined; onSelect?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onSelectCapture?: ((event: React.SyntheticEvent<HTMLTableDataCellElement, Event>) => void) | undefined; onTouchCancel?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchCancelCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchEnd?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchEndCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchMove?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchMoveCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchStart?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onTouchStartCapture?: ((event: React.TouchEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerDown?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerDownCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerMove?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerMoveCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerUp?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerUpCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerCancel?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerCancelCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerEnter?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerEnterCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerLeave?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerLeaveCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOver?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOverCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOut?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onPointerOutCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onGotPointerCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onGotPointerCaptureCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onLostPointerCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onLostPointerCaptureCapture?: ((event: React.PointerEvent<HTMLTableDataCellElement>) => void) | undefined; onScroll?: ((event: React.UIEvent<HTMLTableDataCellElement, UIEvent>) => void) | undefined; onScrollCapture?: ((event: React.UIEvent<HTMLTableDataCellElement, UIEvent>) => void) | undefined; onWheel?: ((event: React.WheelEvent<HTMLTableDataCellElement>) => void) | undefined; onWheelCapture?: ((event: React.WheelEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationStart?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationStartCapture?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationEnd?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationEndCapture?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationIteration?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onAnimationIterationCapture?: ((event: React.AnimationEvent<HTMLTableDataCellElement>) => void) | undefined; onTransitionEnd?: ((event: React.TransitionEvent<HTMLTableDataCellElement>) => void) | undefined; onTransitionEndCapture?: ((event: React.TransitionEvent<HTMLTableDataCellElement>) => void) | undefined; 'data-test-subj'?: string | undefined; width?: string | undefined; readOnly?: boolean | undefined; render?: ((value: any, record: ", { "pluginId": "savedObjectsManagement", "scope": "public", @@ -837,7 +837,7 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - ">) => React.ReactNode) | undefined; colSpan?: number | undefined; rowSpan?: number | undefined; scope?: string | undefined; valign?: \"top\" | \"bottom\" | \"baseline\" | \"middle\" | undefined; dataType?: \"string\" | \"number\" | \"boolean\" | \"date\" | \"auto\" | undefined; isExpander?: boolean | undefined; textOnly?: boolean | undefined; truncateText?: boolean | undefined; isMobileHeader?: boolean | undefined; mobileOptions?: { show?: boolean | undefined; only?: boolean | undefined; render?: ((item: ", + ">) => React.ReactNode) | undefined; colSpan?: number | undefined; headers?: string | undefined; rowSpan?: number | undefined; scope?: string | undefined; valign?: \"top\" | \"bottom\" | \"baseline\" | \"middle\" | undefined; dataType?: \"string\" | \"number\" | \"boolean\" | \"date\" | \"auto\" | undefined; isExpander?: boolean | undefined; textOnly?: boolean | undefined; truncateText?: boolean | undefined; isMobileHeader?: boolean | undefined; mobileOptions?: { show?: boolean | undefined; only?: boolean | undefined; render?: ((item: ", { "pluginId": "savedObjectsManagement", "scope": "public", diff --git a/api_docs/security_solution.json b/api_docs/security_solution.json index ebff5a94fbe2c..b16ae8334f1b0 100644 --- a/api_docs/security_solution.json +++ b/api_docs/security_solution.json @@ -3162,7 +3162,7 @@ "section": "def-common.DataProvider", "text": "DataProvider" }, - ", \"type\" | \"enabled\" | \"id\" | \"name\" | \"excluded\" | \"kqlQuery\" | \"queryMatch\">[]" + ", \"type\" | \"id\" | \"name\" | \"enabled\" | \"excluded\" | \"kqlQuery\" | \"queryMatch\">[]" ], "path": "x-pack/plugins/timelines/common/types/timeline/data_provider/index.ts", "deprecated": false @@ -10228,7 +10228,7 @@ "section": "def-common.RequestBasicOptions", "text": "RequestBasicOptions" }, - ", \"id\" | \"params\" | \"defaultIndex\" | \"filterQuery\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\">" + ", \"id\" | \"defaultIndex\" | \"params\" | \"filterQuery\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\">" ], "path": "x-pack/plugins/security_solution/common/search_strategy/security_solution/network/details/index.ts", "deprecated": false, @@ -15658,7 +15658,7 @@ "section": "def-common.TimelineEventsAllRequestOptions", "text": "TimelineEventsAllRequestOptions" }, - ", \"id\" | \"sort\" | \"fields\" | \"timerange\" | \"language\" | \"defaultIndex\" | \"pagination\" | \"filterQuery\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\" | \"fieldRequested\" | \"excludeEcsData\" | \"authFilter\">" + ", \"id\" | \"sort\" | \"fields\" | \"defaultIndex\" | \"timerange\" | \"language\" | \"pagination\" | \"filterQuery\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\" | \"fieldRequested\" | \"excludeEcsData\" | \"authFilter\">" ], "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts", "deprecated": false, @@ -16280,7 +16280,7 @@ "section": "def-common.TimelineRequestBasicOptions", "text": "TimelineRequestBasicOptions" }, - ", \"id\" | \"params\" | \"defaultIndex\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\">" + ", \"id\" | \"defaultIndex\" | \"params\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\">" ], "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/last_event_time/index.ts", "deprecated": false, @@ -19509,7 +19509,7 @@ "section": "def-common.DataProviderType", "text": "DataProviderType" }, - " | undefined; enabled: boolean; id: string; name: string; excluded: boolean; kqlQuery: string; queryMatch: ", + " | undefined; id: string; name: string; enabled: boolean; excluded: boolean; kqlQuery: string; queryMatch: ", { "pluginId": "timelines", "scope": "common", @@ -19961,7 +19961,7 @@ "section": "def-common.HostsKpiAuthenticationsStrategyResponse", "text": "HostsKpiAuthenticationsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"authenticationsSuccess\" | \"authenticationsSuccessHistogram\" | \"authenticationsFailure\" | \"authenticationsFailureHistogram\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\"> | Pick<", + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"authenticationsSuccess\" | \"authenticationsSuccessHistogram\" | \"authenticationsFailure\" | \"authenticationsFailureHistogram\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\"> | Pick<", { "pluginId": "securitySolution", "scope": "common", @@ -19969,7 +19969,7 @@ "section": "def-common.HostsKpiHostsStrategyResponse", "text": "HostsKpiHostsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"hosts\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"hostsHistogram\"> | Pick<", + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"hosts\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"hostsHistogram\"> | Pick<", { "pluginId": "securitySolution", "scope": "common", @@ -19977,7 +19977,7 @@ "section": "def-common.HostsKpiUniqueIpsStrategyResponse", "text": "HostsKpiUniqueIpsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"uniqueSourceIps\" | \"uniqueSourceIpsHistogram\" | \"uniqueDestinationIps\" | \"uniqueDestinationIpsHistogram\">" + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"uniqueSourceIps\" | \"uniqueSourceIpsHistogram\" | \"uniqueDestinationIps\" | \"uniqueDestinationIpsHistogram\">" ], "path": "x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/index.ts", "deprecated": false, @@ -20486,7 +20486,7 @@ "section": "def-common.NetworkKpiDnsStrategyResponse", "text": "NetworkKpiDnsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"dnsQueries\"> | Pick<", + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"dnsQueries\"> | Pick<", { "pluginId": "securitySolution", "scope": "common", @@ -20494,7 +20494,7 @@ "section": "def-common.NetworkKpiNetworkEventsStrategyResponse", "text": "NetworkKpiNetworkEventsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"networkEvents\"> | Pick<", + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"networkEvents\"> | Pick<", { "pluginId": "securitySolution", "scope": "common", @@ -20502,7 +20502,7 @@ "section": "def-common.NetworkKpiTlsHandshakesStrategyResponse", "text": "NetworkKpiTlsHandshakesStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"tlsHandshakes\"> | Pick<", + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"tlsHandshakes\"> | Pick<", { "pluginId": "securitySolution", "scope": "common", @@ -20510,7 +20510,7 @@ "section": "def-common.NetworkKpiUniqueFlowsStrategyResponse", "text": "NetworkKpiUniqueFlowsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"uniqueFlowId\"> | Pick<", + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"uniqueFlowId\"> | Pick<", { "pluginId": "securitySolution", "scope": "common", @@ -20518,7 +20518,7 @@ "section": "def-common.NetworkKpiUniquePrivateIpsStrategyResponse", "text": "NetworkKpiUniquePrivateIpsStrategyResponse" }, - ", \"warning\" | \"id\" | \"inspect\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"uniqueSourcePrivateIps\" | \"uniqueSourcePrivateIpsHistogram\" | \"uniqueDestinationPrivateIps\" | \"uniqueDestinationPrivateIpsHistogram\">" + ", \"id\" | \"inspect\" | \"warning\" | \"total\" | \"loaded\" | \"isRunning\" | \"isPartial\" | \"isRestored\" | \"uniqueSourcePrivateIps\" | \"uniqueSourcePrivateIpsHistogram\" | \"uniqueDestinationPrivateIps\" | \"uniqueDestinationPrivateIpsHistogram\">" ], "path": "x-pack/plugins/security_solution/common/search_strategy/security_solution/network/kpi/index.ts", "deprecated": false, diff --git a/api_docs/spaces.json b/api_docs/spaces.json index b391ca6ea0dbb..fc7550b607c66 100644 --- a/api_docs/spaces.json +++ b/api_docs/spaces.json @@ -3185,7 +3185,7 @@ "section": "def-server.SavedObjectsRepository", "text": "SavedObjectsRepository" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"deleteByNamespace\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"incrementCounter\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\">" ], "path": "x-pack/plugins/spaces/server/spaces_client/spaces_client_service.ts", "deprecated": false, diff --git a/api_docs/task_manager.json b/api_docs/task_manager.json index 4b7f6dc95e740..4542cdc6fe3f1 100644 --- a/api_docs/task_manager.json +++ b/api_docs/task_manager.json @@ -1245,7 +1245,7 @@ "TaskScheduling", ", \"schedule\" | \"runNow\" | \"ephemeralRunNow\" | \"ensureScheduled\"> & Pick<", "TaskStore", - ", \"remove\" | \"get\" | \"fetch\"> & { removeIfExists: (id: string) => Promise<void>; } & { supportsEphemeralTasks: () => boolean; }" + ", \"remove\" | \"fetch\" | \"get\"> & { removeIfExists: (id: string) => Promise<void>; } & { supportsEphemeralTasks: () => boolean; }" ], "path": "x-pack/plugins/task_manager/server/plugin.ts", "deprecated": false, diff --git a/api_docs/telemetry_collection_manager.json b/api_docs/telemetry_collection_manager.json index 39189b20705ae..7b8178d4499b7 100644 --- a/api_docs/telemetry_collection_manager.json +++ b/api_docs/telemetry_collection_manager.json @@ -74,7 +74,7 @@ "signature": [ "Pick<", "KibanaClient", - ", \"get\" | \"delete\" | \"monitoring\" | \"security\" | \"create\" | \"index\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", + ", \"monitoring\" | \"security\" | \"create\" | \"index\" | \"delete\" | \"get\" | \"update\" | \"closePointInTime\" | \"search\" | \"transform\" | \"eql\" | \"helpers\" | \"emit\" | \"on\" | \"once\" | \"off\" | \"asyncSearch\" | \"autoscaling\" | \"bulk\" | \"cat\" | \"ccr\" | \"clearScroll\" | \"cluster\" | \"count\" | \"danglingIndices\" | \"dataFrameTransformDeprecated\" | \"deleteByQuery\" | \"deleteByQueryRethrottle\" | \"deleteScript\" | \"enrich\" | \"exists\" | \"existsSource\" | \"explain\" | \"features\" | \"fieldCaps\" | \"fleet\" | \"getScript\" | \"getScriptContext\" | \"getScriptLanguages\" | \"getSource\" | \"graph\" | \"ilm\" | \"indices\" | \"info\" | \"ingest\" | \"license\" | \"logstash\" | \"mget\" | \"migration\" | \"ml\" | \"msearch\" | \"msearchTemplate\" | \"mtermvectors\" | \"nodes\" | \"openPointInTime\" | \"ping\" | \"putScript\" | \"rankEval\" | \"reindex\" | \"reindexRethrottle\" | \"renderSearchTemplate\" | \"rollup\" | \"scriptsPainlessExecute\" | \"scroll\" | \"searchShards\" | \"searchTemplate\" | \"searchableSnapshots\" | \"shutdown\" | \"slm\" | \"snapshot\" | \"sql\" | \"ssl\" | \"tasks\" | \"termsEnum\" | \"termvectors\" | \"textStructure\" | \"updateByQuery\" | \"updateByQueryRethrottle\" | \"watcher\" | \"xpack\"> & { transport: { request(params: ", "TransportRequestParams", ", options?: ", "TransportRequestOptions", @@ -95,25 +95,7 @@ "label": "soClient", "description": [], "signature": [ - "{ get: <T = unknown>(type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsBaseOptions", - "text": "SavedObjectsBaseOptions" - }, - ") => Promise<", - "SavedObject", - "<T>>; delete: (type: string, id: string, options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsDeleteOptions", - "text": "SavedObjectsDeleteOptions" - }, - ") => Promise<{}>; create: <T = unknown>(type: string, attributes: T, options?: ", + "{ create: <T = unknown>(type: string, attributes: T, options?: ", { "pluginId": "core", "scope": "server", @@ -171,7 +153,15 @@ "section": "def-server.SavedObjectsCheckConflictsResponse", "text": "SavedObjectsCheckConflictsResponse" }, - ">; find: <T = unknown, A = unknown>(options: ", + ">; delete: (type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsDeleteOptions", + "text": "SavedObjectsDeleteOptions" + }, + ") => Promise<{}>; find: <T = unknown, A = unknown>(options: ", { "pluginId": "core", "scope": "server", @@ -235,6 +225,16 @@ "section": "def-server.SavedObjectsBulkResolveResponse", "text": "SavedObjectsBulkResolveResponse" }, + "<T>>; get: <T = unknown>(type: string, id: string, options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + }, + ") => Promise<", + "SavedObject", "<T>>; resolve: <T = unknown>(type: string, id: string, options?: ", { "pluginId": "core", diff --git a/api_docs/timelines.json b/api_docs/timelines.json index 416f623520394..f9ae6f615d1a7 100644 --- a/api_docs/timelines.json +++ b/api_docs/timelines.json @@ -6361,7 +6361,7 @@ "section": "def-common.DataProvider", "text": "DataProvider" }, - ", \"type\" | \"enabled\" | \"id\" | \"name\" | \"excluded\" | \"kqlQuery\" | \"queryMatch\">[]" + ", \"type\" | \"id\" | \"name\" | \"enabled\" | \"excluded\" | \"kqlQuery\" | \"queryMatch\">[]" ], "path": "x-pack/plugins/timelines/common/types/timeline/data_provider/index.ts", "deprecated": false @@ -9924,7 +9924,7 @@ "section": "def-common.TimelineEventsAllRequestOptions", "text": "TimelineEventsAllRequestOptions" }, - ", \"id\" | \"sort\" | \"fields\" | \"timerange\" | \"language\" | \"defaultIndex\" | \"pagination\" | \"filterQuery\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\" | \"fieldRequested\" | \"excludeEcsData\" | \"authFilter\">" + ", \"id\" | \"sort\" | \"fields\" | \"defaultIndex\" | \"timerange\" | \"language\" | \"pagination\" | \"filterQuery\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\" | \"fieldRequested\" | \"excludeEcsData\" | \"authFilter\">" ], "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts", "deprecated": false, @@ -10546,7 +10546,7 @@ "section": "def-common.TimelineRequestBasicOptions", "text": "TimelineRequestBasicOptions" }, - ", \"id\" | \"params\" | \"defaultIndex\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\">" + ", \"id\" | \"defaultIndex\" | \"params\" | \"docValueFields\" | \"factoryQueryType\" | \"indexType\" | \"entityType\">" ], "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/last_event_time/index.ts", "deprecated": false, @@ -12807,7 +12807,7 @@ "section": "def-common.DataProviderType", "text": "DataProviderType" }, - " | undefined; enabled: boolean; id: string; name: string; excluded: boolean; kqlQuery: string; queryMatch: ", + " | undefined; id: string; name: string; enabled: boolean; excluded: boolean; kqlQuery: string; queryMatch: ", { "pluginId": "timelines", "scope": "common", diff --git a/api_docs/triggers_actions_ui.json b/api_docs/triggers_actions_ui.json index b7e953917aaad..3b5de759e97ee 100644 --- a/api_docs/triggers_actions_ui.json +++ b/api_docs/triggers_actions_ui.json @@ -1353,7 +1353,7 @@ "label": "setAlertProperty", "description": [], "signature": [ - "<Prop extends \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">(key: Prop, value: Pick<", + "<Prop extends \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">(key: Prop, value: Pick<", { "pluginId": "alerting", "scope": "common", @@ -1361,7 +1361,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[Prop] | null) => void" + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[Prop] | null) => void" ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, @@ -1396,7 +1396,7 @@ "section": "def-common.Alert", "text": "Alert" }, - "<Params>, \"enabled\" | \"id\" | \"name\" | \"tags\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[Prop] | null" + "<Params>, \"id\" | \"name\" | \"tags\" | \"enabled\" | \"params\" | \"actions\" | \"throttle\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"notifyWhen\" | \"muteAll\" | \"mutedInstanceIds\" | \"executionStatus\">[Prop] | null" ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, @@ -2115,7 +2115,7 @@ "label": "Alert", "description": [], "signature": [ - "{ enabled: boolean; id: string; name: string; tags: string[]; params: Record<string, unknown>; actions: ", + "{ id: string; name: string; tags: string[]; enabled: boolean; params: Record<string, unknown>; actions: ", { "pluginId": "alerting", "scope": "common", @@ -2187,20 +2187,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "triggersActionsUi", - "id": "def-public.DEFAULT_HIDDEN_ONLY_ON_ALERTS_ACTION_TYPES", - "type": "Array", - "tags": [], - "label": "DEFAULT_HIDDEN_ONLY_ON_ALERTS_ACTION_TYPES", - "description": [], - "signature": [ - "string[]" - ], - "path": "x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "triggersActionsUi", "id": "def-public.RuleTypeRegistryContract", @@ -3216,7 +3202,7 @@ "signature": [ "(props: Pick<", "AlertAddProps", - "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"alertTypeId\" | \"consumer\" | \"canChangeTrigger\" | \"initialValues\" | \"reloadAlerts\">) => React.ReactElement<", + "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"alertTypeId\" | \"consumer\" | \"canChangeTrigger\" | \"initialValues\" | \"reloadAlerts\" | \"ruleTypeIndex\">) => React.ReactElement<", "AlertAddProps", "<Record<string, any>>, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)>" ], @@ -3233,7 +3219,7 @@ "signature": [ "Pick<", "AlertAddProps", - "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"alertTypeId\" | \"consumer\" | \"canChangeTrigger\" | \"initialValues\" | \"reloadAlerts\">" + "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"alertTypeId\" | \"consumer\" | \"canChangeTrigger\" | \"initialValues\" | \"reloadAlerts\" | \"ruleTypeIndex\">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -3252,7 +3238,7 @@ "signature": [ "(props: Pick<", "AlertEditProps", - "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"reloadAlerts\" | \"initialAlert\">) => React.ReactElement<", + "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"reloadAlerts\" | \"initialAlert\" | \"ruleType\">) => React.ReactElement<", "AlertEditProps", "<Record<string, any>>, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)>" ], @@ -3269,7 +3255,7 @@ "signature": [ "Pick<", "AlertEditProps", - "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"reloadAlerts\" | \"initialAlert\">" + "<Record<string, any>>, \"onClose\" | \"metadata\" | \"onSave\" | \"reloadAlerts\" | \"initialAlert\" | \"ruleType\">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 0b6139e8ae9db..e626b24432246 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -18,7 +18,7 @@ Contact [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 239 | 1 | 230 | 18 | +| 238 | 1 | 229 | 18 | ## Client diff --git a/api_docs/usage_collection.json b/api_docs/usage_collection.json index d091924dd664f..c7fb02b1dc378 100644 --- a/api_docs/usage_collection.json +++ b/api_docs/usage_collection.json @@ -461,7 +461,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; } & (WithKibanaRequest extends true ? { kibanaRequest?: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; } & (WithKibanaRequest extends true ? { kibanaRequest?: ", { "pluginId": "core", "scope": "server", @@ -701,7 +701,7 @@ "\nPossible type values in the schema" ], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"long\" | \"double\" | \"text\" | \"short\" | \"float\" | \"integer\" | \"byte\"" + "\"boolean\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"text\" | \"short\" | \"float\" | \"integer\" | \"byte\"" ], "path": "src/plugins/usage_collection/server/collector/types.ts", "deprecated": false, @@ -733,7 +733,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; } & (WithKibanaRequest extends true ? { kibanaRequest?: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; } & (WithKibanaRequest extends true ? { kibanaRequest?: ", { "pluginId": "core", "scope": "server", @@ -803,7 +803,7 @@ "section": "def-server.SavedObjectsClient", "text": "SavedObjectsClient" }, - ", \"get\" | \"delete\" | \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; } & (WithKibanaRequest extends true ? { kibanaRequest?: ", + ", \"create\" | \"bulkCreate\" | \"checkConflicts\" | \"delete\" | \"find\" | \"bulkGet\" | \"bulkResolve\" | \"get\" | \"resolve\" | \"update\" | \"collectMultiNamespaceReferences\" | \"updateObjectsSpaces\" | \"bulkUpdate\" | \"removeReferencesTo\" | \"openPointInTimeForType\" | \"closePointInTime\" | \"createPointInTimeFinder\" | \"errors\">; } & (WithKibanaRequest extends true ? { kibanaRequest?: ", { "pluginId": "core", "scope": "server", diff --git a/api_docs/vis_type_pie.json b/api_docs/vis_type_pie.json index 66f8da4dc56fc..0bb24caeb5558 100644 --- a/api_docs/vis_type_pie.json +++ b/api_docs/vis_type_pie.json @@ -78,9 +78,9 @@ "signature": [ "{ id?: string | undefined; params?: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, diff --git a/api_docs/visualizations.json b/api_docs/visualizations.json index d131d522b3515..9877a9bc18321 100644 --- a/api_docs/visualizations.json +++ b/api_docs/visualizations.json @@ -1012,7 +1012,7 @@ "section": "def-public.SerializedVisData", "text": "SerializedVisData" }, - ">; }, never>, \"type\" | \"data\" | \"id\" | \"title\" | \"description\" | \"params\" | \"uiState\">) => Promise<void>" + ">; }, never>, \"data\" | \"type\" | \"id\" | \"title\" | \"description\" | \"params\" | \"uiState\">) => Promise<void>" ], "path": "src/plugins/visualizations/public/vis.ts", "deprecated": false, @@ -1057,7 +1057,7 @@ "section": "def-public.SerializedVisData", "text": "SerializedVisData" }, - ">; }, never>, \"type\" | \"data\" | \"id\" | \"title\" | \"description\" | \"params\" | \"uiState\">" + ">; }, never>, \"data\" | \"type\" | \"id\" | \"title\" | \"description\" | \"params\" | \"uiState\">" ], "path": "src/plugins/visualizations/public/vis.ts", "deprecated": false, @@ -1280,13 +1280,21 @@ }, "; field?: string | undefined; index?: string | undefined; params?: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined; source?: string | undefined; sourceParams?: ", + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined; source?: string | undefined; sourceParams?: ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -2100,13 +2108,21 @@ "description": [], "signature": [ { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">" ], "path": "src/plugins/visualizations/public/vis_schemas.ts", "deprecated": false @@ -4180,13 +4196,21 @@ }, "; format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>; }>)[] | undefined, string]" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">; }>)[] | undefined, string]" ], "path": "src/plugins/visualizations/common/prepare_log_table.ts", "deprecated": false, @@ -4238,13 +4262,21 @@ }, "; format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>; }" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">; }" ], "path": "src/plugins/visualizations/common/expression_functions/xy_dimension.ts", "deprecated": false, @@ -4602,7 +4634,7 @@ "label": "VisualizeEmbeddableFactoryContract", "description": [], "signature": [ - "{ readonly type: \"visualization\"; inject: (_state: ", + "{ inject: (_state: ", { "pluginId": "embeddable", "scope": "common", @@ -4638,7 +4670,7 @@ }, "; references: ", "SavedObjectReference", - "[]; }; create: (input: ", + "[]; }; readonly type: \"visualization\"; create: (input: ", { "pluginId": "visualizations", "scope": "public", @@ -5568,13 +5600,21 @@ }, "; field?: string | undefined; index?: string | undefined; params?: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>> | undefined; source?: string | undefined; sourceParams?: ", + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + "> | undefined; source?: string | undefined; sourceParams?: ", { "pluginId": "@kbn/utility-types", "scope": "server", @@ -5994,13 +6034,21 @@ }, "; format: ", { - "pluginId": "expressions", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibExpressionsPluginApi", + "docId": "kibFieldFormatsPluginApi", "section": "def-common.SerializedFieldFormat", "text": "SerializedFieldFormat" }, - "<Record<string, any>>; }>)[] | undefined, string]" + "<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatParams", + "text": "FieldFormatParams" + }, + ">; }>)[] | undefined, string]" ], "path": "src/plugins/visualizations/common/prepare_log_table.ts", "deprecated": false, diff --git a/api_docs/visualize.json b/api_docs/visualize.json index 86196b0ba34c0..e1a0a134cde94 100644 --- a/api_docs/visualize.json +++ b/api_docs/visualize.json @@ -114,11 +114,11 @@ "description": [], "signature": [ { - "pluginId": "savedObjects", + "pluginId": "discover", "scope": "public", - "docId": "kibSavedObjectsPluginApi", - "section": "def-public.SavedObject", - "text": "SavedObject" + "docId": "kibDiscoverPluginApi", + "section": "def-public.SavedSearch", + "text": "SavedSearch" }, " | undefined" ], diff --git a/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx b/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx index 133b96f44da88..737b9d8708f29 100644 --- a/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx +++ b/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx @@ -33,13 +33,28 @@ At a super high-level, Kibana is composed of **plugins**, **core**, and **Kibana <DocAccordion buttonContent="(Internal only) FAQ: Should I put my code in a plugin or a package?" color="warning"> <DocCallOut color="warning"> -If it's stateful, it has to go in a plugin, but packages are often a good choices for stateless utilities. Stateless code exported publicly from a plugin will increase the page load bundle size of _every single page_, even if none of those plugin's services are actually needed. With packages, however, only code that is needed for the current page is downloaded. +When the [Bazel migration](https://github.com/elastic/kibana/blob/master/legacy_rfcs/text/0015_bazel.md) is complete, all code, including plugins, will be a package. With that, packages won't be required to be in the `packages/` directory and can be located somewhere that makes more sense structurally. -The downside however is that the packages folder is far away from the plugins folder so having a part of your code in a plugin and the rest in a package may make it hard to find, leading to duplication. +In the meantime, the following can be used to determine whether it makes sense to add code to a package inside the `packages` folder, or a plugin inside `src/plugins` or `x-pack/plugins`. -The Operations team hopes to resolve this conundrum by supporting co-located packages and plugins and automatically putting all stateless code inside a package. You can track this work by following [this issue](https://github.com/elastic/kibana/issues/112886). -Until then, consider whether it makes sense to logically separate the code, and consider the size of the exports, when determining whether you should put stateless public exports in a package or a plugin. +**If the code is stateful, it has to be exposed from a plugin's <DocLink id="kibPlatformIntro" section="lifecycle-methods" text="lifecycle methods"/>. Do not statically export stateful code.** + +Benefits to packages: + +1. <b>_Potentially_ reduced page load time</b>. All code that is statically exported from plugins will be downloaded on _every single page load_, even if that code isn't needed. With packages, only code that is imported is downloaded, which can be minimized by using async imports. +2. <b>Puts the consumer is in charge of how and when to async import</b>. If a consumer async imports code exported from a plugin, it makes no difference, because of the above point. It's already been downloaded. However, simply moving code into a package is _not_ a guaranteed performance improvement. It does give the consumer the power to make smart performance choices, however. If they require code from multiple packages, the consumer can async import from multiple packages at the same time. Read more in our <DocLink id="kibDevPerformance" text="performance docs"/>. + +Downsides to packages: + +1. <b>It's not <DocLink id="kibDevPrinciples" text="organized by domain"/></b>. The packages folder is far away from the plugins folder. Having your stateless code in a plugin and the rest in a package may make it hard to find, leading to duplication. The Operations team hopes to fix this by supporting packages and plugins existing in the same folder. You can track this work by following [this issue](https://github.com/elastic/kibana/issues/112886). + +2. <b>Development overhead</b>. Developers have to run `yarn kbn watch` to have changes rebuilt automatically. [Phase II](https://github.com/elastic/kibana/blob/master/legacy_rfcs/text/0015_bazel.md#phase-ii---docs-developer-experience) of the Bazel migration work will bring the development experience on par with plugin development. This work can be tracked [here](https://github.com/elastic/kibana/issues/104519). + +3. <b>Development performance</b>. Rebuild time is typically longer than it would be for the same code in a plugin. The reasons are captured in [this issue](https://github.com/elastic/kibana/issues/107648). The ops team is actively working to reduce this performance increase. + + +As you can see, the answer to "Should I put my code in a plugin or a package" is 'It Depends'. If you are still having a hard time determining what the best path location is, reach out to the Kibana Operations Team (#kibana-operations) for help. </DocCallOut> </DocAccordion> diff --git a/docs/api/logstash-configuration-management/create-logstash.asciidoc b/docs/api/logstash-configuration-management/create-logstash.asciidoc index 9bd5a9028ee9a..ffbbf182249ec 100644 --- a/docs/api/logstash-configuration-management/create-logstash.asciidoc +++ b/docs/api/logstash-configuration-management/create-logstash.asciidoc @@ -27,7 +27,16 @@ experimental[] Create a centrally-managed Logstash pipeline, or update an existi (Required, string) The pipeline definition. `settings`:: - (Optional, object) The pipeline settings. Supported settings, represented as object keys, are `pipeline.workers`, `pipeline.batch.size`, `pipeline.batch.delay`, `queue.type`, `queue.max_bytes`, and `queue.checkpoint.writes`. + (Optional, object) The pipeline settings. Supported settings, represented as object keys, include the following: + + * `pipeline.workers` + * `pipeline.batch.size` + * `pipeline.batch.delay` + * `pipeline.ecs_compatibility` + * `pipeline.ordered` + * `queue.type` + * `queue.max_bytes` + * `queue.checkpoint.writes` [[logstash-configuration-management-api-create-codes]] ==== Response code diff --git a/docs/api/short-urls.asciidoc b/docs/api/short-urls.asciidoc new file mode 100644 index 0000000000000..ded639c897f3f --- /dev/null +++ b/docs/api/short-urls.asciidoc @@ -0,0 +1,9 @@ +[[short-urls-api]] +== Short URLs APIs + +Manage {kib} short URLs. + +include::short-urls/create-short-url.asciidoc[] +include::short-urls/get-short-url.asciidoc[] +include::short-urls/delete-short-url.asciidoc[] +include::short-urls/resolve-short-url.asciidoc[] diff --git a/docs/api/short-urls/create-short-url.asciidoc b/docs/api/short-urls/create-short-url.asciidoc new file mode 100644 index 0000000000000..a9138a4c555da --- /dev/null +++ b/docs/api/short-urls/create-short-url.asciidoc @@ -0,0 +1,86 @@ +[[short-urls-api-create]] +=== Create short URL API +++++ +<titleabbrev>Create short URL</titleabbrev> +++++ + +experimental[] Create a {kib} short URL. {kib} URLs may be long and cumbersome, short URLs are much +easier to remember and share. + +Short URLs are created by specifying the locator ID and locator parameters. When a short URL is +resolved, the locator ID and locator parameters are used to redirect user to the right {kib} page. + + +[[short-urls-api-create-request]] +==== Request + +`POST <kibana host>:<port>/api/short_url` + + +[[short-urls-api-create-request-body]] +==== Request body + +`locatorId`:: + (Required, string) ID of the locator. + +`params`:: + (Required, object) Object which contains all necessary parameters for the given locator to resolve + to a {kib} location. ++ +WARNING: When you create a short URL, locator params are not validated, which allows you to pass +arbitrary and ill-formed data into the API that can break {kib}. Make sure +any data that you send to the API is properly formed. + +`slug`:: + (Optional, string) A custom short URL slug. Slug is the part of the short URL that identifies it. + You can provide a custom slug which consists of latin alphabet letters, numbers and `-._` + characters. The slug must be at least 3 characters long, but no longer than 255 characters. + +`humanReadableSlug`:: + (Optional, boolean) When the `slug` parameter is omitted, the API will generate a random + human-readable slug, if `humanReadableSlug` is set to `true`. + + +[[short-urls-api-create-response-codes]] +==== Response code + +`200`:: + Indicates a successful call. + + +[[short-urls-api-create-example]] +==== Example + +[source,sh] +-------------------------------------------------- +$ curl -X POST api/short_url -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d ' +{ + "locatorId": "LOCATOR_ID", + "params": {}, + "humanReadableSlug": true +}' +-------------------------------------------------- +// KIBANA + +The API returns the following: + +[source,sh] +-------------------------------------------------- +{ + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", <1> + "slug": "adjective-adjective-noun", <2> + "locator": { + "id": "LOCATOR_ID", + "version": "x.x.x", <3> + "state": {} <4> + }, + "accessCount": 0, + "accessDate": 1632680100000, + "createDate": 1632680100000 +} +-------------------------------------------------- + +<1> A random ID is automatically generated. +<2> A random human-readable slug is automatically generated if the `humanReadableSlug` parameter is set to `true`. If set to `false` a random short string is generated. +<3> The version of {kib} when short URL was created is stored. +<4> Locator params provided as `params` property are stored. diff --git a/docs/api/short-urls/delete-short-url.asciidoc b/docs/api/short-urls/delete-short-url.asciidoc new file mode 100644 index 0000000000000..f405ccf1a7472 --- /dev/null +++ b/docs/api/short-urls/delete-short-url.asciidoc @@ -0,0 +1,39 @@ +[[short-urls-api-delete]] +=== Delete short URL API +++++ +<titleabbrev>Delete short URL</titleabbrev> +++++ + +experimental[] Delete a {kib} short URL. + + +[[short-urls-api-delete-request]] +==== Request + +`DELETE <kibana host>:<port>/api/short_url/<id>` + + +[[short-urls-api-delete-path-params]] +==== Path parameters + +`id`:: + (Required, string) The short URL ID that you want to remove. + + +[[short-urls-api-delete-response-codes]] +==== Response code + +`200`:: + Indicates a successful call. + + +[[short-urls-api-delete-example]] +==== Example + +Delete a short URL `12345` ID: + +[source,sh] +-------------------------------------------------- +$ curl -X DELETE api/short_url/12345 +-------------------------------------------------- +// KIBANA diff --git a/docs/api/short-urls/get-short-url.asciidoc b/docs/api/short-urls/get-short-url.asciidoc new file mode 100644 index 0000000000000..bf4303d442fb0 --- /dev/null +++ b/docs/api/short-urls/get-short-url.asciidoc @@ -0,0 +1,56 @@ +[[short-urls-api-get]] +=== Get short URL API +++++ +<titleabbrev>Get short URL</titleabbrev> +++++ + +experimental[] Retrieve a single {kib} short URL. + +[[short-urls-api-get-request]] +==== Request + +`GET <kibana host>:<port>/api/short_url/<id>` + + +[[short-urls-api-get-params]] +==== Path parameters + +`id`:: + (Required, string) The ID of the short URL. + + +[[short-urls-api-get-codes]] +==== Response code + +`200`:: + Indicates a successful call. + + +[[short-urls-api-get-example]] +==== Example + +Retrieve the short URL with the `12345` ID: + +[source,sh] +-------------------------------------------------- +$ curl -X GET api/short_url/12345 +-------------------------------------------------- +// KIBANA + +The API returns the following: + +[source,sh] +-------------------------------------------------- +{ + "id": "12345", + "slug": "adjective-adjective-noun", + "locator": { + "id": "LOCATOR_ID", + "version": "x.x.x", + "state": {} + }, + "accessCount": 0, + "accessDate": 1632680100000, + "createDate": 1632680100000 +} +-------------------------------------------------- diff --git a/docs/api/short-urls/resolve-short-url.asciidoc b/docs/api/short-urls/resolve-short-url.asciidoc new file mode 100644 index 0000000000000..32ad7ba7625c0 --- /dev/null +++ b/docs/api/short-urls/resolve-short-url.asciidoc @@ -0,0 +1,56 @@ +[[short-urls-api-resolve]] +=== Resolve short URL API +++++ +<titleabbrev>Resolve short URL</titleabbrev> +++++ + +experimental[] Resolve a single {kib} short URL by its slug. + +[[short-urls-api-resolve-request]] +==== Request + +`GET <kibana host>:<port>/api/short_url/_slug/<slug>` + + +[[short-urls-api-resolve-params]] +==== Path parameters + +`slug`:: + (Required, string) The slug of the short URL. + + +[[short-urls-api-resolve-codes]] +==== Response code + +`200`:: + Indicates a successful call. + + +[[short-urls-api-resolve-example]] +==== Example + +Retrieve the short URL with the `hello-world` ID: + +[source,sh] +-------------------------------------------------- +$ curl -X GET api/short_url/_slug/hello-world +-------------------------------------------------- +// KIBANA + +The API returns the following: + +[source,sh] +-------------------------------------------------- +{ + "id": "12345", + "slug": "hello-world", + "locator": { + "id": "LOCATOR_ID", + "version": "x.x.x", + "state": {} + }, + "accessCount": 0, + "accessDate": 1632680100000, + "createDate": 1632680100000 +} +-------------------------------------------------- diff --git a/docs/api/url-shortening.asciidoc b/docs/api/url-shortening.asciidoc deleted file mode 100644 index ffe1d925e5dcb..0000000000000 --- a/docs/api/url-shortening.asciidoc +++ /dev/null @@ -1,62 +0,0 @@ -[[url-shortening-api]] -== Shorten URL API -++++ -<titleabbrev>Shorten URL</titleabbrev> -++++ - -experimental[] Convert a {kib} URL into a token. {kib} URLs contain the state of the application, which makes them long and cumbersome. -Internet Explorer has URL length restrictions, and some wiki and markup parsers don't do well with the full-length version of the {kib} URL. - -Short URLs are designed to make sharing {kib} URLs easier. - -[float] -[[url-shortening-api-request]] -=== Request - -`POST <kibana host>:<port>/api/shorten_url` - -[float] -[[url-shortening-api-request-body]] -=== Request body - -`url`:: - (Required, string) The {kib} URL that you want to shorten, relative to `/app/kibana`. - -[float] -[[url-shortening-api-response-body]] -=== Response body - -urlId:: A top-level property that contains the shortened URL token for the provided request body. - -[float] -[[url-shortening-api-codes]] -=== Response code - -`200`:: - Indicates a successful call. - -[float] -[[url-shortening-api-example]] -=== Example - -[source,sh] --------------------------------------------------- -$ curl -X POST api/shorten_url -{ - "url": "/app/kibana#/dashboard?_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:'1',w:24,x:0,y:0),id:'8f4d0c00-4c86-11e8-b3d7-01146121b73d',panelIndex:'1',type:visualization,version:'7.0.0-alpha1')),query:(language:lucene,query:''),timeRestore:!f,title:'New%20Dashboard',viewMode:edit)" -} --------------------------------------------------- -// KIBANA - -The API returns the following: - -[source,sh] --------------------------------------------------- -{ - "urlId": "f73b295ff92718b26bc94edac766d8e3" -} --------------------------------------------------- - -For easy sharing, construct the shortened {kib} URL: - -`http://localhost:5601/goto/f73b295ff92718b26bc94edac766d8e3` diff --git a/docs/apm/api.asciidoc b/docs/apm/api.asciidoc index fe4c8a9280158..5f81a41e93df8 100644 --- a/docs/apm/api.asciidoc +++ b/docs/apm/api.asciidoc @@ -484,8 +484,7 @@ An example is below. [[api-create-apm-index-pattern]] ==== Customize the APM index pattern -As an alternative to updating <<apm-settings-in-kibana,`apm_oss.indexPattern`>> in your `kibana.yml` configuration file, -you can use Kibana's <<saved-objects-api-update,update object API>> to update the default APM index pattern on the fly. +Use Kibana's <<saved-objects-api-update,update object API>> to update the default APM index pattern on the fly. The following example sets the default APM app index pattern to `some-other-pattern-*`: diff --git a/docs/apm/troubleshooting.asciidoc b/docs/apm/troubleshooting.asciidoc index 6e0c3b1decda8..84cdb9876dc63 100644 --- a/docs/apm/troubleshooting.asciidoc +++ b/docs/apm/troubleshooting.asciidoc @@ -76,7 +76,7 @@ If you change the default, you must also configure the `setup.template.name` and See {apm-server-ref}/configuration-template.html[Load the Elasticsearch index template]. If the Elasticsearch index template has already been successfully loaded to the index, you can customize the indices that the APM app uses to display data. -Navigate to *APM* > *Settings* > *Indices*, and change all `apm_oss.*Pattern` values to +Navigate to *APM* > *Settings* > *Indices*, and change all `xpack.apm.indices.*` values to include the new index pattern. For example: `customIndexName-*`. [float] diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 0e728a4dada24..3d1fcd51837a3 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -28,10 +28,6 @@ allowing users to configure their advanced settings, also known as uiSettings within the code. -|{kib-repo}blob/{branch}/src/plugins/apm_oss/README.asciidoc[apmOss] -|undefined - - |{kib-repo}blob/{branch}/src/plugins/bfetch/README.md[bfetch] |bfetch allows to batch HTTP requests and streams responses back. @@ -350,7 +346,7 @@ The plugin exposes the static DefaultEditorController class to consume. |{kib-repo}blob/{branch}/x-pack/plugins/apm/readme.md[apm] -|Local setup documentation +|undefined |{kib-repo}blob/{branch}/x-pack/plugins/banners/README.md[banners] @@ -362,7 +358,8 @@ The plugin exposes the static DefaultEditorController class to consume. |{kib-repo}blob/{branch}/x-pack/plugins/cases/README.md[cases] -|Case management in Kibana +|[![Issues][issues-shield]][issues-url] +[![Pull Requests][pr-shield]][pr-url] |{kib-repo}blob/{branch}/x-pack/plugins/cloud/README.md[cloud] @@ -620,10 +617,6 @@ in their infrastructure. |This plugins adopts some conventions in addition to or in place of conventions in Kibana (at the time of the plugin's creation): -|{kib-repo}blob/{branch}/x-pack/plugins/xpack_legacy/README.md[xpackLegacy] -|Contains HTTP endpoints and UiSettings that are slated for removal. - - |=== include::{kibana-root}/src/plugins/dashboard/README.asciidoc[leveloffset=+1] diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index c8ccdfeedb83f..e79bc7a0db026 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -9,6 +9,7 @@ ```typescript readonly links: { readonly settings: string; + readonly elasticStackGetStarted: string; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; @@ -145,6 +146,9 @@ readonly links: { readonly networkMap: string; readonly troubleshootGaps: string; }; + readonly securitySolution: { + readonly trustedApps: string; + }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; @@ -236,6 +240,7 @@ readonly links: { upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; + apiKeysLearnMore: string; }>; readonly ecs: { readonly guide: string; diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index 04c2495cf3f1d..51101c8804680 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,4 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | <code>string</code> | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | <code>string</code> | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | <code>{</code><br/><code> readonly settings: string;</code><br/><code> readonly apm: {</code><br/><code> readonly kibanaSettings: string;</code><br/><code> readonly supportedServiceMaps: string;</code><br/><code> readonly customLinks: string;</code><br/><code> readonly droppedTransactionSpans: string;</code><br/><code> readonly upgrading: string;</code><br/><code> readonly metaData: string;</code><br/><code> };</code><br/><code> readonly canvas: {</code><br/><code> readonly guide: string;</code><br/><code> };</code><br/><code> readonly dashboard: {</code><br/><code> readonly guide: string;</code><br/><code> readonly drilldowns: string;</code><br/><code> readonly drilldownsTriggerPicker: string;</code><br/><code> readonly urlDrilldownTemplateSyntax: string;</code><br/><code> readonly urlDrilldownVariables: string;</code><br/><code> };</code><br/><code> readonly discover: Record<string, string>;</code><br/><code> readonly filebeat: {</code><br/><code> readonly base: string;</code><br/><code> readonly installation: string;</code><br/><code> readonly configuration: string;</code><br/><code> readonly elasticsearchOutput: string;</code><br/><code> readonly elasticsearchModule: string;</code><br/><code> readonly startup: string;</code><br/><code> readonly exportedFields: string;</code><br/><code> readonly suricataModule: string;</code><br/><code> readonly zeekModule: string;</code><br/><code> };</code><br/><code> readonly auditbeat: {</code><br/><code> readonly base: string;</code><br/><code> readonly auditdModule: string;</code><br/><code> readonly systemModule: string;</code><br/><code> };</code><br/><code> readonly metricbeat: {</code><br/><code> readonly base: string;</code><br/><code> readonly configure: string;</code><br/><code> readonly httpEndpoint: string;</code><br/><code> readonly install: string;</code><br/><code> readonly start: string;</code><br/><code> };</code><br/><code> readonly enterpriseSearch: {</code><br/><code> readonly base: string;</code><br/><code> readonly appSearchBase: string;</code><br/><code> readonly workplaceSearchBase: string;</code><br/><code> };</code><br/><code> readonly heartbeat: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly libbeat: {</code><br/><code> readonly getStarted: string;</code><br/><code> };</code><br/><code> readonly logstash: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly functionbeat: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly winlogbeat: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly aggs: {</code><br/><code> readonly composite: string;</code><br/><code> readonly composite_missing_bucket: string;</code><br/><code> readonly date_histogram: string;</code><br/><code> readonly date_range: string;</code><br/><code> readonly date_format_pattern: string;</code><br/><code> readonly filter: string;</code><br/><code> readonly filters: string;</code><br/><code> readonly geohash_grid: string;</code><br/><code> readonly histogram: string;</code><br/><code> readonly ip_range: string;</code><br/><code> readonly range: string;</code><br/><code> readonly significant_terms: string;</code><br/><code> readonly terms: string;</code><br/><code> readonly avg: string;</code><br/><code> readonly avg_bucket: string;</code><br/><code> readonly max_bucket: string;</code><br/><code> readonly min_bucket: string;</code><br/><code> readonly sum_bucket: string;</code><br/><code> readonly cardinality: string;</code><br/><code> readonly count: string;</code><br/><code> readonly cumulative_sum: string;</code><br/><code> readonly derivative: string;</code><br/><code> readonly geo_bounds: string;</code><br/><code> readonly geo_centroid: string;</code><br/><code> readonly max: string;</code><br/><code> readonly median: string;</code><br/><code> readonly min: string;</code><br/><code> readonly moving_avg: string;</code><br/><code> readonly percentile_ranks: string;</code><br/><code> readonly serial_diff: string;</code><br/><code> readonly std_dev: string;</code><br/><code> readonly sum: string;</code><br/><code> readonly top_hits: string;</code><br/><code> };</code><br/><code> readonly runtimeFields: {</code><br/><code> readonly overview: string;</code><br/><code> readonly mapping: string;</code><br/><code> };</code><br/><code> readonly scriptedFields: {</code><br/><code> readonly scriptFields: string;</code><br/><code> readonly scriptAggs: string;</code><br/><code> readonly painless: string;</code><br/><code> readonly painlessApi: string;</code><br/><code> readonly painlessLangSpec: string;</code><br/><code> readonly painlessSyntax: string;</code><br/><code> readonly painlessWalkthrough: string;</code><br/><code> readonly luceneExpressions: string;</code><br/><code> };</code><br/><code> readonly search: {</code><br/><code> readonly sessions: string;</code><br/><code> readonly sessionLimits: string;</code><br/><code> };</code><br/><code> readonly indexPatterns: {</code><br/><code> readonly introduction: string;</code><br/><code> readonly fieldFormattersNumber: string;</code><br/><code> readonly fieldFormattersString: string;</code><br/><code> readonly runtimeFields: string;</code><br/><code> };</code><br/><code> readonly addData: string;</code><br/><code> readonly kibana: string;</code><br/><code> readonly upgradeAssistant: string;</code><br/><code> readonly rollupJobs: string;</code><br/><code> readonly elasticsearch: Record<string, string>;</code><br/><code> readonly siem: {</code><br/><code> readonly privileges: string;</code><br/><code> readonly guide: string;</code><br/><code> readonly gettingStarted: string;</code><br/><code> readonly ml: string;</code><br/><code> readonly ruleChangeLog: string;</code><br/><code> readonly detectionsReq: string;</code><br/><code> readonly networkMap: string;</code><br/><code> };</code><br/><code> readonly query: {</code><br/><code> readonly eql: string;</code><br/><code> readonly kueryQuerySyntax: string;</code><br/><code> readonly luceneQuerySyntax: string;</code><br/><code> readonly percolate: string;</code><br/><code> readonly queryDsl: string;</code><br/><code> readonly autocompleteChanges: string;</code><br/><code> };</code><br/><code> readonly date: {</code><br/><code> readonly dateMath: string;</code><br/><code> readonly dateMathIndexNames: string;</code><br/><code> };</code><br/><code> readonly management: Record<string, string>;</code><br/><code> readonly ml: Record<string, string>;</code><br/><code> readonly transforms: Record<string, string>;</code><br/><code> readonly visualize: Record<string, string>;</code><br/><code> readonly apis: Readonly<{</code><br/><code> bulkIndexAlias: string;</code><br/><code> byteSizeUnits: string;</code><br/><code> createAutoFollowPattern: string;</code><br/><code> createFollower: string;</code><br/><code> createIndex: string;</code><br/><code> createSnapshotLifecyclePolicy: string;</code><br/><code> createRoleMapping: string;</code><br/><code> createRoleMappingTemplates: string;</code><br/><code> createRollupJobsRequest: string;</code><br/><code> createApiKey: string;</code><br/><code> createPipeline: string;</code><br/><code> createTransformRequest: string;</code><br/><code> cronExpressions: string;</code><br/><code> executeWatchActionModes: string;</code><br/><code> indexExists: string;</code><br/><code> openIndex: string;</code><br/><code> putComponentTemplate: string;</code><br/><code> painlessExecute: string;</code><br/><code> painlessExecuteAPIContexts: string;</code><br/><code> putComponentTemplateMetadata: string;</code><br/><code> putSnapshotLifecyclePolicy: string;</code><br/><code> putIndexTemplateV1: string;</code><br/><code> putWatch: string;</code><br/><code> simulatePipeline: string;</code><br/><code> timeUnits: string;</code><br/><code> updateTransform: string;</code><br/><code> }>;</code><br/><code> readonly observability: Readonly<{</code><br/><code> guide: string;</code><br/><code> infrastructureThreshold: string;</code><br/><code> logsThreshold: string;</code><br/><code> metricsThreshold: string;</code><br/><code> monitorStatus: string;</code><br/><code> monitorUptime: string;</code><br/><code> tlsCertificate: string;</code><br/><code> uptimeDurationAnomaly: string;</code><br/><code> }>;</code><br/><code> readonly alerting: Record<string, string>;</code><br/><code> readonly maps: Record<string, string>;</code><br/><code> readonly monitoring: Record<string, string>;</code><br/><code> readonly security: Readonly<{</code><br/><code> apiKeyServiceSettings: string;</code><br/><code> clusterPrivileges: string;</code><br/><code> elasticsearchSettings: string;</code><br/><code> elasticsearchEnableSecurity: string;</code><br/><code> indicesPrivileges: string;</code><br/><code> kibanaTLS: string;</code><br/><code> kibanaPrivileges: string;</code><br/><code> mappingRoles: string;</code><br/><code> mappingRolesFieldRules: string;</code><br/><code> runAsPrivilege: string;</code><br/><code> }>;</code><br/><code> readonly spaces: Readonly<{</code><br/><code> kibanaLegacyUrlAliases: string;</code><br/><code> kibanaDisableLegacyUrlAliasesApi: string;</code><br/><code> }>;</code><br/><code> readonly watcher: Record<string, string>;</code><br/><code> readonly ccs: Record<string, string>;</code><br/><code> readonly plugins: Record<string, string>;</code><br/><code> readonly snapshotRestore: Record<string, string>;</code><br/><code> readonly ingest: Record<string, string>;</code><br/><code> readonly fleet: Readonly<{</code><br/><code> guide: string;</code><br/><code> fleetServer: string;</code><br/><code> fleetServerAddFleetServer: string;</code><br/><code> settings: string;</code><br/><code> settingsFleetServerHostSettings: string;</code><br/><code> troubleshooting: string;</code><br/><code> elasticAgent: string;</code><br/><code> datastreams: string;</code><br/><code> datastreamsNamingScheme: string;</code><br/><code> upgradeElasticAgent: string;</code><br/><code> upgradeElasticAgent712lower: string;</code><br/><code> }>;</code><br/><code> readonly ecs: {</code><br/><code> readonly guide: string;</code><br/><code> };</code><br/><code> readonly clients: {</code><br/><code> readonly guide: string;</code><br/><code> readonly goOverview: string;</code><br/><code> readonly javaIndex: string;</code><br/><code> readonly jsIntro: string;</code><br/><code> readonly netGuide: string;</code><br/><code> readonly perlGuide: string;</code><br/><code> readonly phpGuide: string;</code><br/><code> readonly pythonGuide: string;</code><br/><code> readonly rubyOverview: string;</code><br/><code> readonly rustGuide: string;</code><br/><code> };</code><br/><code> }</code> | | - +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | <code>{</code><br/><code> readonly settings: string;</code><br/><code> readonly apm: {</code><br/><code> readonly kibanaSettings: string;</code><br/><code> readonly supportedServiceMaps: string;</code><br/><code> readonly customLinks: string;</code><br/><code> readonly droppedTransactionSpans: string;</code><br/><code> readonly upgrading: string;</code><br/><code> readonly metaData: string;</code><br/><code> };</code><br/><code> readonly canvas: {</code><br/><code> readonly guide: string;</code><br/><code> };</code><br/><code> readonly dashboard: {</code><br/><code> readonly guide: string;</code><br/><code> readonly drilldowns: string;</code><br/><code> readonly drilldownsTriggerPicker: string;</code><br/><code> readonly urlDrilldownTemplateSyntax: string;</code><br/><code> readonly urlDrilldownVariables: string;</code><br/><code> };</code><br/><code> readonly discover: Record<string, string>;</code><br/><code> readonly filebeat: {</code><br/><code> readonly base: string;</code><br/><code> readonly installation: string;</code><br/><code> readonly configuration: string;</code><br/><code> readonly elasticsearchOutput: string;</code><br/><code> readonly elasticsearchModule: string;</code><br/><code> readonly startup: string;</code><br/><code> readonly exportedFields: string;</code><br/><code> readonly suricataModule: string;</code><br/><code> readonly zeekModule: string;</code><br/><code> };</code><br/><code> readonly auditbeat: {</code><br/><code> readonly base: string;</code><br/><code> readonly auditdModule: string;</code><br/><code> readonly systemModule: string;</code><br/><code> };</code><br/><code> readonly metricbeat: {</code><br/><code> readonly base: string;</code><br/><code> readonly configure: string;</code><br/><code> readonly httpEndpoint: string;</code><br/><code> readonly install: string;</code><br/><code> readonly start: string;</code><br/><code> };</code><br/><code> readonly enterpriseSearch: {</code><br/><code> readonly base: string;</code><br/><code> readonly appSearchBase: string;</code><br/><code> readonly workplaceSearchBase: string;</code><br/><code> };</code><br/><code> readonly heartbeat: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly libbeat: {</code><br/><code> readonly getStarted: string;</code><br/><code> };</code><br/><code> readonly logstash: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly functionbeat: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly winlogbeat: {</code><br/><code> readonly base: string;</code><br/><code> };</code><br/><code> readonly aggs: {</code><br/><code> readonly composite: string;</code><br/><code> readonly composite_missing_bucket: string;</code><br/><code> readonly date_histogram: string;</code><br/><code> readonly date_range: string;</code><br/><code> readonly date_format_pattern: string;</code><br/><code> readonly filter: string;</code><br/><code> readonly filters: string;</code><br/><code> readonly geohash_grid: string;</code><br/><code> readonly histogram: string;</code><br/><code> readonly ip_range: string;</code><br/><code> readonly range: string;</code><br/><code> readonly significant_terms: string;</code><br/><code> readonly terms: string;</code><br/><code> readonly avg: string;</code><br/><code> readonly avg_bucket: string;</code><br/><code> readonly max_bucket: string;</code><br/><code> readonly min_bucket: string;</code><br/><code> readonly sum_bucket: string;</code><br/><code> readonly cardinality: string;</code><br/><code> readonly count: string;</code><br/><code> readonly cumulative_sum: string;</code><br/><code> readonly derivative: string;</code><br/><code> readonly geo_bounds: string;</code><br/><code> readonly geo_centroid: string;</code><br/><code> readonly max: string;</code><br/><code> readonly median: string;</code><br/><code> readonly min: string;</code><br/><code> readonly moving_avg: string;</code><br/><code> readonly percentile_ranks: string;</code><br/><code> readonly serial_diff: string;</code><br/><code> readonly std_dev: string;</code><br/><code> readonly sum: string;</code><br/><code> readonly top_hits: string;</code><br/><code> };</code><br/><code> readonly runtimeFields: {</code><br/><code> readonly overview: string;</code><br/><code> readonly mapping: string;</code><br/><code> };</code><br/><code> readonly scriptedFields: {</code><br/><code> readonly scriptFields: string;</code><br/><code> readonly scriptAggs: string;</code><br/><code> readonly painless: string;</code><br/><code> readonly painlessApi: string;</code><br/><code> readonly painlessLangSpec: string;</code><br/><code> readonly painlessSyntax: string;</code><br/><code> readonly painlessWalkthrough: string;</code><br/><code> readonly luceneExpressions: string;</code><br/><code> };</code><br/><code> readonly search: {</code><br/><code> readonly sessions: string;</code><br/><code> readonly sessionLimits: string;</code><br/><code> };</code><br/><code> readonly indexPatterns: {</code><br/><code> readonly introduction: string;</code><br/><code> readonly fieldFormattersNumber: string;</code><br/><code> readonly fieldFormattersString: string;</code><br/><code> readonly runtimeFields: string;</code><br/><code> };</code><br/><code> readonly addData: string;</code><br/><code> readonly kibana: string;</code><br/><code> readonly upgradeAssistant: string;</code><br/><code> readonly rollupJobs: string;</code><br/><code> readonly elasticsearch: Record<string, string>;</code><br/><code> readonly siem: {</code><br/><code> readonly privileges: string;</code><br/><code> readonly guide: string;</code><br/><code> readonly gettingStarted: string;</code><br/><code> readonly ml: string;</code><br/><code> readonly ruleChangeLog: string;</code><br/><code> readonly detectionsReq: string;</code><br/><code> readonly networkMap: string;</code><br/><code> };</code><br/><code> readonly securitySolution: {</code><br/><code> readonly trustedApps: string;</code><br/><code> };</code><br/><code> readonly query: {</code><br/><code> readonly eql: string;</code><br/><code> readonly kueryQuerySyntax: string;</code><br/><code> readonly luceneQuerySyntax: string;</code><br/><code> readonly percolate: string;</code><br/><code> readonly queryDsl: string;</code><br/><code> readonly autocompleteChanges: string;</code><br/><code> };</code><br/><code> readonly date: {</code><br/><code> readonly dateMath: string;</code><br/><code> readonly dateMathIndexNames: string;</code><br/><code> };</code><br/><code> readonly management: Record<string, string>;</code><br/><code> readonly ml: Record<string, string>;</code><br/><code> readonly transforms: Record<string, string>;</code><br/><code> readonly visualize: Record<string, string>;</code><br/><code> readonly apis: Readonly<{</code><br/><code> bulkIndexAlias: string;</code><br/><code> byteSizeUnits: string;</code><br/><code> createAutoFollowPattern: string;</code><br/><code> createFollower: string;</code><br/><code> createIndex: string;</code><br/><code> createSnapshotLifecyclePolicy: string;</code><br/><code> createRoleMapping: string;</code><br/><code> createRoleMappingTemplates: string;</code><br/><code> createRollupJobsRequest: string;</code><br/><code> createApiKey: string;</code><br/><code> createPipeline: string;</code><br/><code> createTransformRequest: string;</code><br/><code> cronExpressions: string;</code><br/><code> executeWatchActionModes: string;</code><br/><code> indexExists: string;</code><br/><code> openIndex: string;</code><br/><code> putComponentTemplate: string;</code><br/><code> painlessExecute: string;</code><br/><code> painlessExecuteAPIContexts: string;</code><br/><code> putComponentTemplateMetadata: string;</code><br/><code> putSnapshotLifecyclePolicy: string;</code><br/><code> putIndexTemplateV1: string;</code><br/><code> putWatch: string;</code><br/><code> simulatePipeline: string;</code><br/><code> timeUnits: string;</code><br/><code> updateTransform: string;</code><br/><code> }>;</code><br/><code> readonly observability: Readonly<{</code><br/><code> guide: string;</code><br/><code> infrastructureThreshold: string;</code><br/><code> logsThreshold: string;</code><br/><code> metricsThreshold: string;</code><br/><code> monitorStatus: string;</code><br/><code> monitorUptime: string;</code><br/><code> tlsCertificate: string;</code><br/><code> uptimeDurationAnomaly: string;</code><br/><code> }>;</code><br/><code> readonly alerting: Record<string, string>;</code><br/><code> readonly maps: Record<string, string>;</code><br/><code> readonly monitoring: Record<string, string>;</code><br/><code> readonly security: Readonly<{</code><br/><code> apiKeyServiceSettings: string;</code><br/><code> clusterPrivileges: string;</code><br/><code> elasticsearchSettings: string;</code><br/><code> elasticsearchEnableSecurity: string;</code><br/><code> indicesPrivileges: string;</code><br/><code> kibanaTLS: string;</code><br/><code> kibanaPrivileges: string;</code><br/><code> mappingRoles: string;</code><br/><code> mappingRolesFieldRules: string;</code><br/><code> runAsPrivilege: string;</code><br/><code> }>;</code><br/><code> readonly watcher: Record<string, string>;</code><br/><code> readonly ccs: Record<string, string>;</code><br/><code> readonly plugins: Record<string, string>;</code><br/><code> readonly snapshotRestore: Record<string, string>;</code><br/><code> readonly ingest: Record<string, string>;</code><br/><code> readonly fleet: Readonly<{</code><br/><code> guide: string;</code><br/><code> fleetServer: string;</code><br/><code> fleetServerAddFleetServer: string;</code><br/><code> settings: string;</code><br/><code> settingsFleetServerHostSettings: string;</code><br/><code> troubleshooting: string;</code><br/><code> elasticAgent: string;</code><br/><code> datastreams: string;</code><br/><code> datastreamsNamingScheme: string;</code><br/><code> upgradeElasticAgent: string;</code><br/><code> upgradeElasticAgent712lower: string;</code><br/><code> }>;</code><br/><code> readonly ecs: {</code><br/><code> readonly guide: string;</code><br/><code> };</code><br/><code> readonly clients: {</code><br/><code> readonly guide: string;</code><br/><code> readonly goOverview: string;</code><br/><code> readonly javaIndex: string;</code><br/><code> readonly jsIntro: string;</code><br/><code> readonly netGuide: string;</code><br/><code> readonly perlGuide: string;</code><br/><code> readonly phpGuide: string;</code><br/><code> readonly pythonGuide: string;</code><br/><code> readonly rubyOverview: string;</code><br/><code> readonly rustGuide: string;</code><br/><code> };</code><br/><code> }</code> | | \ No newline at end of file diff --git a/docs/index.asciidoc b/docs/index.asciidoc index e286e42f2c421..f9ed2abc4b8cf 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -13,12 +13,8 @@ include::{docs-root}/shared/versions/stack/{source_branch}.asciidoc[] :es-docker-image: {es-docker-repo}:{version} :blob: {kib-repo}blob/{branch}/ :security-ref: https://www.elastic.co/community/security/ -:Data-Sources: Data Views -:Data-source: Data view :data-source: data view -:Data-sources: Data views :data-sources: data views -:A-data-source: A data view :a-data-source: a data view include::{docs-root}/shared/attributes.asciidoc[] diff --git a/docs/management/action-types.asciidoc b/docs/management/action-types.asciidoc index 92adbaf97d8c5..93d0ee3d2cab6 100644 --- a/docs/management/action-types.asciidoc +++ b/docs/management/action-types.asciidoc @@ -35,10 +35,14 @@ a| <<server-log-action-type, ServerLog>> | Add a message to a Kibana log. -a| <<servicenow-action-type, ServiceNow>> +a| <<servicenow-action-type, ServiceNow ITSM>> | Create an incident in ServiceNow. +a| <<servicenow-sir-action-type, ServiceNow SecOps>> + +| Create a security incident in ServiceNow. + a| <<slack-action-type, Slack>> | Send a message to a Slack channel or user. diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 6fd83e8af3d15..6bac5e7940dbb 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -426,6 +426,7 @@ because requests can be spread across all shard copies. However, results might be inconsistent because different shards might be in different refresh states. [[search-includefrozen]]`search:includeFrozen`:: +**This setting is deprecated and will not be supported as of 9.0.** Includes {ref}/frozen-indices.html[frozen indices] in results. Searching through frozen indices might increase the search time. This setting is off by default. Users must opt-in to include frozen indices. diff --git a/docs/management/connectors/action-types/servicenow-sir.asciidoc b/docs/management/connectors/action-types/servicenow-sir.asciidoc new file mode 100644 index 0000000000000..4556746284d5b --- /dev/null +++ b/docs/management/connectors/action-types/servicenow-sir.asciidoc @@ -0,0 +1,89 @@ +[role="xpack"] +[[servicenow-sir-action-type]] +=== ServiceNow connector and action +++++ +<titleabbrev>ServiceNow SecOps</titleabbrev> +++++ + +The ServiceNow SecOps connector uses the https://docs.servicenow.com/bundle/orlando-application-development/page/integrate/inbound-rest/concept/c_TableAPI.html[V2 Table API] to create ServiceNow security incidents. + +[float] +[[servicenow-sir-connector-configuration]] +==== Connector configuration + +ServiceNow SecOps connectors have the following configuration properties. + +Name:: The name of the connector. The name is used to identify a connector in the **Stack Management** UI connector listing, and in the connector list when configuring an action. +URL:: ServiceNow instance URL. +Username:: Username for HTTP Basic authentication. +Password:: Password for HTTP Basic authentication. + +The ServiceNow user requires at minimum read, create, and update access to the Security Incident table and read access to the https://docs.servicenow.com/bundle/paris-platform-administration/page/administer/localization/reference/r_ChoicesTable.html[sys_choice]. If you don't provide access to sys_choice, then the choices will not render. + +[float] +[[servicenow-sir-connector-networking-configuration]] +==== Connector networking configuration + +Use the <<action-settings, Action configuration settings>> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. + +[float] +[[Preconfigured-servicenow-sir-configuration]] +==== Preconfigured connector type + +[source,text] +-- + my-servicenow-sir: + name: preconfigured-servicenow-connector-type + actionTypeId: .servicenow-sir + config: + apiUrl: https://dev94428.service-now.com/ + secrets: + username: testuser + password: passwordkeystorevalue +-- + +Config defines information for the connector type. + +`apiUrl`:: An address that corresponds to *URL*. + +Secrets defines sensitive information for the connector type. + +`username`:: A string that corresponds to *Username*. +`password`:: A string that corresponds to *Password*. Should be stored in the <<creating-keystore, {kib} keystore>>. + +[float] +[[define-servicenow-sir-ui]] +==== Define connector in Stack Management + +Define ServiceNow SecOps connector properties. + +[role="screenshot"] +image::management/connectors/images/servicenow-sir-connector.png[ServiceNow SecOps connector] + +Test ServiceNow SecOps action parameters. + +[role="screenshot"] +image::management/connectors/images/servicenow-sir-params-test.png[ServiceNow SecOps params test] + +[float] +[[servicenow-sir-action-configuration]] +==== Action configuration + +ServiceNow SecOps actions have the following configuration properties. + +Short description:: A short description for the incident, used for searching the contents of the knowledge base. +Source Ips:: A list of source IPs related to the incident. The IPs will be added as observables to the security incident. +Destination Ips:: A list of destination IPs related to the incident. The IPs will be added as observables to the security incident. +Malware URLs:: A list of malware URLs related to the incident. The URLs will be added as observables to the security incident. +Malware Hashes:: A list of malware hashes related to the incident. The hashes will be added as observables to the security incident. +Priority:: The priority of the incident. +Category:: The category of the incident. +Subcategory:: The subcategory of the incident. +Description:: The details about the incident. +Additional comments:: Additional information for the client, such as how to troubleshoot the issue. + +[float] +[[configuring-servicenow-sir]] +==== Configure ServiceNow SecOps + +ServiceNow offers free https://developer.servicenow.com/dev.do#!/guides/madrid/now-platform/pdi-guide/obtaining-a-pdi[Personal Developer Instances], which you can use to test incidents. diff --git a/docs/management/connectors/action-types/servicenow.asciidoc b/docs/management/connectors/action-types/servicenow.asciidoc index 3a4134cbf982e..cf5244a9e3f9e 100644 --- a/docs/management/connectors/action-types/servicenow.asciidoc +++ b/docs/management/connectors/action-types/servicenow.asciidoc @@ -2,16 +2,16 @@ [[servicenow-action-type]] === ServiceNow connector and action ++++ -<titleabbrev>ServiceNow</titleabbrev> +<titleabbrev>ServiceNow ITSM</titleabbrev> ++++ -The ServiceNow connector uses the https://docs.servicenow.com/bundle/orlando-application-development/page/integrate/inbound-rest/concept/c_TableAPI.html[V2 Table API] to create ServiceNow incidents. +The ServiceNow ITSM connector uses the https://docs.servicenow.com/bundle/orlando-application-development/page/integrate/inbound-rest/concept/c_TableAPI.html[V2 Table API] to create ServiceNow incidents. [float] [[servicenow-connector-configuration]] ==== Connector configuration -ServiceNow connectors have the following configuration properties. +ServiceNow ITSM connectors have the following configuration properties. Name:: The name of the connector. The name is used to identify a connector in the **Stack Management** UI connector listing, and in the connector list when configuring an action. URL:: ServiceNow instance URL. @@ -55,12 +55,12 @@ Secrets defines sensitive information for the connector type. [[define-servicenow-ui]] ==== Define connector in Stack Management -Define ServiceNow connector properties. +Define ServiceNow ITSM connector properties. [role="screenshot"] image::management/connectors/images/servicenow-connector.png[ServiceNow connector] -Test ServiceNow action parameters. +Test ServiceNow ITSM action parameters. [role="screenshot"] image::management/connectors/images/servicenow-params-test.png[ServiceNow params test] @@ -69,11 +69,13 @@ image::management/connectors/images/servicenow-params-test.png[ServiceNow params [[servicenow-action-configuration]] ==== Action configuration -ServiceNow actions have the following configuration properties. +ServiceNow ITSM actions have the following configuration properties. Urgency:: The extent to which the incident resolution can delay. Severity:: The severity of the incident. Impact:: The effect an incident has on business. Can be measured by the number of affected users or by how critical it is to the business in question. +Category:: The category of the incident. +Subcategory:: The category of the incident. Short description:: A short description for the incident, used for searching the contents of the knowledge base. Description:: The details about the incident. Additional comments:: Additional information for the client, such as how to troubleshoot the issue. diff --git a/docs/management/connectors/images/servicenow-sir-params-test.png b/docs/management/connectors/images/servicenow-sir-params-test.png index 16ea83c60b3c3..80103a4272bfa 100644 Binary files a/docs/management/connectors/images/servicenow-sir-params-test.png and b/docs/management/connectors/images/servicenow-sir-params-test.png differ diff --git a/docs/management/connectors/index.asciidoc b/docs/management/connectors/index.asciidoc index 033b1c3ac150e..536d05705181d 100644 --- a/docs/management/connectors/index.asciidoc +++ b/docs/management/connectors/index.asciidoc @@ -6,6 +6,7 @@ include::action-types/teams.asciidoc[] include::action-types/pagerduty.asciidoc[] include::action-types/server-log.asciidoc[] include::action-types/servicenow.asciidoc[] +include::action-types/servicenow-sir.asciidoc[] include::action-types/swimlane.asciidoc[] include::action-types/slack.asciidoc[] include::action-types/webhook.asciidoc[] diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index fb96f68355330..fc20685885df7 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -87,22 +87,22 @@ Changing these settings may disable features of the APM App. | `xpack.apm.agent.migrations.enabled` {ess-icon} | Set to `false` to disable cloud APM migrations. Defaults to `true`. -| `xpack.apm.errorIndices` {ess-icon} - | Matcher for all {apm-server-ref}/error-indices.html[error indices]. Defaults to `apm-*`. +| `xpack.apm.indices.error` {ess-icon} + | Matcher for all {apm-server-ref}/error-indices.html[error indices]. Defaults to `logs-apm*,apm-*`. -| `xpack.apm.onboardingIndices` {ess-icon} +| `xpack.apm.indices.onboarding` {ess-icon} | Matcher for all onboarding indices. Defaults to `apm-*`. -| `xpack.apm.spanIndices` {ess-icon} - | Matcher for all {apm-server-ref}/span-indices.html[span indices]. Defaults to `apm-*`. +| `xpack.apm.indices.span` {ess-icon} + | Matcher for all {apm-server-ref}/span-indices.html[span indices]. Defaults to `traces-apm*,apm-*`. -| `xpack.apm.transactionIndices` {ess-icon} - | Matcher for all {apm-server-ref}/transaction-indices.html[transaction indices]. Defaults to `apm-*`. +| `xpack.apm.indices.transaction` {ess-icon} + | Matcher for all {apm-server-ref}/transaction-indices.html[transaction indices]. Defaults to `traces-apm*,apm-*`. -| `xpack.apm.metricsIndices` {ess-icon} - | Matcher for all {apm-server-ref}/metricset-indices.html[metrics indices]. Defaults to `apm-*`. +| `xpack.apm.indices.metric` {ess-icon} + | Matcher for all {apm-server-ref}/metricset-indices.html[metrics indices]. Defaults to `metrics-apm*,apm-*`. -| `xpack.apm.sourcemapIndices` {ess-icon} +| `xpack.apm.indices.sourcemap` {ess-icon} | Matcher for all {apm-server-ref}/sourcemap-indices.html[source map indices]. Defaults to `apm-*`. |=== diff --git a/docs/settings/general-infra-logs-ui-settings.asciidoc b/docs/settings/general-infra-logs-ui-settings.asciidoc index 282239dcf166c..1e6dcf012206b 100644 --- a/docs/settings/general-infra-logs-ui-settings.asciidoc +++ b/docs/settings/general-infra-logs-ui-settings.asciidoc @@ -1,31 +1,28 @@ -[cols="2*<"] -|=== -| `xpack.infra.enabled` - | deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported."] - Set to `false` to disable the Logs and Metrics app plugin {kib}. Defaults to `true`. -| `xpack.infra.sources.default.logAlias` - | Index pattern for matching indices that contain log data. Defaults to `filebeat-*,kibana_sample_data_logs*`. To match multiple wildcard patterns, use a comma to separate the names, with no space after the comma. For example, `logstash-app1-*,default-logs-*`. +`xpack.infra.enabled`:: +deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported."] +Set to `false` to disable the Logs and Metrics app plugin {kib}. Defaults to `true`. -| `xpack.infra.sources.default.metricAlias` - | Index pattern for matching indices that contain Metricbeat data. Defaults to `metricbeat-*`. To match multiple wildcard patterns, use a comma to separate the names, with no space after the comma. For example, `logstash-app1-*,default-logs-*`. +`xpack.infra.sources.default.logAlias`:: +Index pattern for matching indices that contain log data. Defaults to `filebeat-*,kibana_sample_data_logs*`. To match multiple wildcard patterns, use a comma to separate the names, with no space after the comma. For example, `logstash-app1-*,default-logs-*`. -| `xpack.infra.sources.default.fields.timestamp` - | Timestamp used to sort log entries. Defaults to `@timestamp`. +`xpack.infra.sources.default.metricAlias`:: +Index pattern for matching indices that contain Metricbeat data. Defaults to `metricbeat-*`. To match multiple wildcard patterns, use a comma to separate the names, with no space after the comma. For example, `logstash-app1-*,default-logs-*`. -| `xpack.infra.sources.default.fields.message` - | Fields used to display messages in the Logs app. Defaults to `['message', '@message']`. +`xpack.infra.sources.default.fields.timestamp`:: +Timestamp used to sort log entries. Defaults to `@timestamp`. -| `xpack.infra.sources.default.fields.tiebreaker` - | Field used to break ties between two entries with the same timestamp. Defaults to `_doc`. +`xpack.infra.sources.default.fields.message`:: +Fields used to display messages in the Logs app. Defaults to `['message', '@message']`. -| `xpack.infra.sources.default.fields.host` - | Field used to identify hosts. Defaults to `host.name`. +`xpack.infra.sources.default.fields.tiebreaker`:: +Field used to break ties between two entries with the same timestamp. Defaults to `_doc`. -| `xpack.infra.sources.default.fields.container` - | Field used to identify Docker containers. Defaults to `container.id`. +`xpack.infra.sources.default.fields.host`:: +Field used to identify hosts. Defaults to `host.name`. -| `xpack.infra.sources.default.fields.pod` - | Field used to identify Kubernetes pods. Defaults to `kubernetes.pod.uid`. +`xpack.infra.sources.default.fields.container`:: +Field used to identify Docker containers. Defaults to `container.id`. -|=== +`xpack.infra.sources.default.fields.pod`:: +Field used to identify Kubernetes pods. Defaults to `kubernetes.pod.uid`. \ No newline at end of file diff --git a/docs/settings/ml-settings.asciidoc b/docs/settings/ml-settings.asciidoc index 59fa236e08275..e67876c76df0d 100644 --- a/docs/settings/ml-settings.asciidoc +++ b/docs/settings/ml-settings.asciidoc @@ -11,18 +11,14 @@ enabled by default. [[general-ml-settings-kb]] ==== General {ml} settings -[cols="2*<"] -|=== -| `xpack.ml.enabled` {ess-icon} - | deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported."] - Set to `true` (default) to enable {kib} {ml-features}. + - + - If set to `false` in `kibana.yml`, the {ml} icon is hidden in this {kib} - instance. If `xpack.ml.enabled` is set to `true` in `elasticsearch.yml`, however, - you can still use the {ml} APIs. To disable {ml} entirely, see the - {ref}/ml-settings.html[{es} {ml} settings]. - -|=== +`xpack.ml.enabled` {ess-icon}:: +deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported."] +Set to `true` (default) to enable {kib} {ml-features}. + ++ +If set to `false` in `kibana.yml`, the {ml} icon is hidden in this {kib} +instance. If `xpack.ml.enabled` is set to `true` in `elasticsearch.yml`, however, +you can still use the {ml} APIs. To disable {ml} entirely, refer to +{ref}/ml-settings.html[{es} {ml} settings]. [[advanced-ml-settings-kb]] ==== Advanced {ml} settings diff --git a/docs/settings/reporting-settings.asciidoc b/docs/settings/reporting-settings.asciidoc index 560f2d850c6d5..af10430ef8d01 100644 --- a/docs/settings/reporting-settings.asciidoc +++ b/docs/settings/reporting-settings.asciidoc @@ -79,11 +79,6 @@ The protocol for accessing {kib}, typically `http` or `https`. [[xpack-kibanaServer-hostname]] `xpack.reporting.kibanaServer.hostname`:: The hostname for accessing {kib}, if different from the <<server-host, `server.host`>> value. -NOTE: Reporting authenticates requests on the {kib} page only when the hostname matches the -<<xpack-kibanaServer-hostname, `xpack.reporting.kibanaServer.hostname`>> setting. Therefore Reporting fails if the -set value redirects to another server. For that reason, `"0"` is an invalid setting -because, in the Reporting browser, it becomes an automatic redirect to `"0.0.0.0"`. - [float] [[reporting-job-queue-settings]] ==== Background job settings diff --git a/docs/settings/search-sessions-settings.asciidoc b/docs/settings/search-sessions-settings.asciidoc index abd6a8f12b568..7b03cd23a9023 100644 --- a/docs/settings/search-sessions-settings.asciidoc +++ b/docs/settings/search-sessions-settings.asciidoc @@ -7,37 +7,26 @@ Configure the search session settings in your `kibana.yml` configuration file. +`xpack.data_enhanced.search.sessions.enabled` {ess-icon}:: +Set to `true` (default) to enable search sessions. -[cols="2*<"] -|=== -a| `xpack.data_enhanced.` -`search.sessions.enabled` {ess-icon} -| Set to `true` (default) to enable search sessions. +`xpack.data_enhanced.search.sessions.trackingInterval` {ess-icon}:: +The frequency for updating the state of a search session. The default is `10s`. -a| `xpack.data_enhanced.` -`search.sessions.trackingInterval` {ess-icon} -| The frequency for updating the state of a search session. The default is `10s`. - -a| `xpack.data_enhanced.` -`search.sessions.pageSize` {ess-icon} -| How many search sessions {kib} processes at once while monitoring +`xpack.data_enhanced.search.sessions.pageSize` {ess-icon}:: +How many search sessions {kib} processes at once while monitoring session progress. The default is `100`. -a| `xpack.data_enhanced.` -`search.sessions.notTouchedTimeout` {ess-icon} -| How long {kib} stores search results from unsaved sessions, +`xpack.data_enhanced.search.sessions.notTouchedTimeout` {ess-icon}:: +How long {kib} stores search results from unsaved sessions, after the last search in the session completes. The default is `5m`. -a| `xpack.data_enhanced.` -`search.sessions.notTouchedInProgressTimeout` {ess-icon} -| How long a search session can run after a user navigates away without saving a session. The default is `1m`. +`xpack.data_enhanced.search.sessions.notTouchedInProgressTimeout` {ess-icon}:: +How long a search session can run after a user navigates away without saving a session. The default is `1m`. -a| `xpack.data_enhanced.` -`search.sessions.maxUpdateRetries` {ess-icon} -| How many retries {kib} can perform while attempting to save a search session. The default is `3`. +`xpack.data_enhanced.search.sessions.maxUpdateRetries` {ess-icon}:: +How many retries {kib} can perform while attempting to save a search session. The default is `3`. -a| `xpack.data_enhanced.` -`search.sessions.defaultExpiration` {ess-icon} -| How long search session results are stored before they are deleted. +`xpack.data_enhanced.search.sessions.defaultExpiration` {ess-icon}:: +How long search session results are stored before they are deleted. Extending a search session resets the expiration by the same value. The default is `7d`. -|=== diff --git a/docs/settings/spaces-settings.asciidoc b/docs/settings/spaces-settings.asciidoc index 8504464da1dfb..969adb93185d0 100644 --- a/docs/settings/spaces-settings.asciidoc +++ b/docs/settings/spaces-settings.asciidoc @@ -5,24 +5,23 @@ <titleabbrev>Spaces settings</titleabbrev> ++++ -By default, Spaces is enabled in Kibana, and you can secure Spaces using -roles when Security is enabled. +By default, spaces is enabled in {kib}. To secure spaces, <<security-settings-kb,enable security>>. -[float] -[[spaces-settings]] -==== Spaces settings +`xpack.spaces.enabled`:: +deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported and it will not be possible to disable this plugin."] +To enable spaces, set to `true`. +The default is `true`. -[cols="2*<"] -|=== -| `xpack.spaces.enabled` - | deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported."] - Set to `true` (default) to enable Spaces in {kib}. - This setting is deprecated. Starting in 8.0, it will not be possible to disable this plugin. +`xpack.spaces.maxSpaces`:: +The maximum number of spaces that you can use with the {kib} instance. Some {kib} operations +return all spaces using a single `_search` from {es}, so you must +configure this setting lower than the `index.max_result_window` in {es}. +The default is `1000`. -| `xpack.spaces.maxSpaces` - | The maximum amount of Spaces that can be used with this instance of {kib}. Some operations - in {kib} return all spaces using a single `_search` from {es}, so this must be - set lower than the `index.max_result_window` in {es}. - Defaults to `1000`. - -|=== +`monitoring.cluster_alerts-allowedSpaces` {ess-icon}:: +Specifies the spaces where cluster alerts are automatically generated. +You must specify all spaces where you want to generate alerts, including the default space. +When the default space is unspecified, {kib} is unable to generate an alert for the default space. +{es} clusters that run on {es} services are all containers. To send monitoring data +from your self-managed {es} installation to {es} services, set to `false`. +The default is `true`. diff --git a/docs/user/api.asciidoc b/docs/user/api.asciidoc index 12e200bb0ba27..e17d52675437e 100644 --- a/docs/user/api.asciidoc +++ b/docs/user/api.asciidoc @@ -1,8 +1,8 @@ [[api]] = REST API -Some {kib} features are provided via a REST API, which is ideal for creating an -integration with {kib}, or automating certain aspects of configuring and +Some {kib} features are provided via a REST API, which is ideal for creating an +integration with {kib}, or automating certain aspects of configuring and deploying {kib}. [float] @@ -18,15 +18,15 @@ NOTE: The {kib} Console supports only Elasticsearch APIs. You are unable to inte [float] [[api-authentication]] === Authentication -The {kib} APIs support key- and token-based authentication. +The {kib} APIs support key- and token-based authentication. [float] [[token-api-authentication]] ==== Token-based authentication -To use token-based authentication, you use the same username and password that you use to log into Elastic. -In a given HTTP tool, and when available, you can select to use its 'Basic Authentication' option, -which is where the username and password are stored in order to be passed as part of the call. +To use token-based authentication, you use the same username and password that you use to log into Elastic. +In a given HTTP tool, and when available, you can select to use its 'Basic Authentication' option, +which is where the username and password are stored in order to be passed as part of the call. [float] [[key-authentication]] @@ -65,7 +65,7 @@ For all APIs, you must use a request header. The {kib} APIs support the `kbn-xsr * XSRF protections are disabled using the <<settings-xsrf-disableProtection, `server.xsrf.disableProtection`>> setting `Content-Type: application/json`:: - Applicable only when you send a payload in the API request. {kib} API requests and responses use JSON. + Applicable only when you send a payload in the API request. {kib} API requests and responses use JSON. Typically, if you include the `kbn-xsrf` header, you must also include the `Content-Type` header. Request header example: @@ -97,6 +97,6 @@ include::{kib-repo-dir}/api/actions-and-connectors.asciidoc[] include::{kib-repo-dir}/api/dashboard-api.asciidoc[] include::{kib-repo-dir}/api/logstash-configuration-management.asciidoc[] include::{kib-repo-dir}/api/machine-learning.asciidoc[] -include::{kib-repo-dir}/api/url-shortening.asciidoc[] +include::{kib-repo-dir}/api/short-urls.asciidoc[] include::{kib-repo-dir}/api/task-manager/health.asciidoc[] include::{kib-repo-dir}/api/upgrade-assistant.asciidoc[] diff --git a/docs/user/reporting/index.asciidoc b/docs/user/reporting/index.asciidoc index 148e9f8ee14a5..c1e131cc057e0 100644 --- a/docs/user/reporting/index.asciidoc +++ b/docs/user/reporting/index.asciidoc @@ -13,9 +13,9 @@ You access the options from the *Share* menu in the toolbar. The sharing options include the following: -* *PDF Reports* — Generate and download a PDF file of a dashboard, visualization, or *Canvas* workpad. +* *PDF Reports* — Generate and download a PDF file of a dashboard, visualization, or *Canvas* workpad. PDF reports are a link:https://www.elastic.co/subscriptions[subscription feature]. -* *PNG Reports* — Generate and download a PNG file of a dashboard or visualization. +* *PNG Reports* — Generate and download a PNG file of a dashboard or visualization. PNG reports are a link:https://www.elastic.co/subscriptions[subscription feature]. * *CSV Reports* — Generate and download a CSV file of a *Discover* saved search. diff --git a/examples/dashboard_embeddable_examples/kibana.json b/examples/dashboard_embeddable_examples/kibana.json index e13f19194ef06..ba0c4a84836e7 100644 --- a/examples/dashboard_embeddable_examples/kibana.json +++ b/examples/dashboard_embeddable_examples/kibana.json @@ -16,6 +16,5 @@ "githubTeam": "kibana-presentation" }, "description": "Example app that shows how to embed a dashboard in an application", - "optionalPlugins": [], - "requiredBundles": ["esUiShared"] + "optionalPlugins": [] } diff --git a/examples/dashboard_embeddable_examples/public/app.tsx b/examples/dashboard_embeddable_examples/public/app.tsx index 8a6b5a90a22a8..c44d67c49f3d7 100644 --- a/examples/dashboard_embeddable_examples/public/app.tsx +++ b/examples/dashboard_embeddable_examples/public/app.tsx @@ -18,9 +18,10 @@ import { EuiSideNav, } from '@elastic/eui'; import 'brace/mode/json'; -import { AppMountParameters } from '../../../src/core/public'; +import { AppMountParameters, IUiSettingsClient } from '../../../src/core/public'; import { DashboardEmbeddableByValue } from './by_value/embeddable'; import { DashboardStart } from '../../../src/plugins/dashboard/public'; +import { KibanaContextProvider } from '../../../src/plugins/kibana_react/public'; interface PageDef { title: string; @@ -58,9 +59,14 @@ interface Props { DashboardContainerByValueRenderer: ReturnType< DashboardStart['getDashboardContainerByValueRenderer'] >; + uiSettings: IUiSettingsClient; } -const DashboardEmbeddableExplorerApp = ({ basename, DashboardContainerByValueRenderer }: Props) => { +const DashboardEmbeddableExplorerApp = ({ + basename, + DashboardContainerByValueRenderer, + uiSettings, +}: Props) => { const pages: PageDef[] = [ { title: 'By value dashboard embeddable', @@ -83,16 +89,18 @@ const DashboardEmbeddableExplorerApp = ({ basename, DashboardContainerByValueRen )); return ( - <Router basename={basename}> - <EuiPage> - <EuiPageSideBar> - <Nav pages={pages} /> - </EuiPageSideBar> - <EuiPageContent> - <EuiPageContentBody>{routes}</EuiPageContentBody> - </EuiPageContent> - </EuiPage> - </Router> + <KibanaContextProvider services={{ uiSettings }}> + <Router basename={basename}> + <EuiPage> + <EuiPageSideBar> + <Nav pages={pages} /> + </EuiPageSideBar> + <EuiPageContent> + <EuiPageContentBody>{routes}</EuiPageContentBody> + </EuiPageContent> + </EuiPage> + </Router> + </KibanaContextProvider> ); }; diff --git a/examples/dashboard_embeddable_examples/public/by_value/input_editor.tsx b/examples/dashboard_embeddable_examples/public/by_value/input_editor.tsx index 3e6487ea0b88c..a723712f395d0 100644 --- a/examples/dashboard_embeddable_examples/public/by_value/input_editor.tsx +++ b/examples/dashboard_embeddable_examples/public/by_value/input_editor.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiButton } from '@elastic/eui'; -import { JsonEditor } from '../../../../src/plugins/es_ui_shared/public'; +import { CodeEditor } from '../../../../src/plugins/kibana_react/public'; export const InputEditor = <T,>(props: { input: T; onSubmit: (value: T) => void }) => { const input = JSON.stringify(props.input, null, 4); @@ -26,12 +26,13 @@ export const InputEditor = <T,>(props: { input: T; onSubmit: (value: T) => void }, [input]); return ( <> - <JsonEditor + <CodeEditor + languageId={'json'} value={value} - onUpdate={(v) => setValue(v.data.raw)} - euiCodeEditorProps={{ - 'data-test-subj': 'dashboardEmbeddableByValueInputEditor', - }} + width={'100%'} + height={'400px'} + onChange={(v) => setValue(v)} + data-test-subj={'dashboardEmbeddableByValueInputEditor'} /> <EuiButton onClick={() => props.onSubmit(JSON.parse(value))} diff --git a/examples/dashboard_embeddable_examples/public/plugin.tsx b/examples/dashboard_embeddable_examples/public/plugin.tsx index 5fd3e01f2ca71..14bd71523ef2f 100644 --- a/examples/dashboard_embeddable_examples/public/plugin.tsx +++ b/examples/dashboard_embeddable_examples/public/plugin.tsx @@ -27,7 +27,7 @@ export class DashboardEmbeddableExamples implements Plugin<void, void, {}, Start title: 'Dashboard embeddable examples', navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { - const [, depsStart] = await core.getStartServices(); + const [coreStart, depsStart] = await core.getStartServices(); const { renderApp } = await import('./app'); await depsStart.embeddableExamples.createSampleData(); return renderApp( @@ -35,6 +35,7 @@ export class DashboardEmbeddableExamples implements Plugin<void, void, {}, Start basename: params.appBasePath, DashboardContainerByValueRenderer: depsStart.dashboard.getDashboardContainerByValueRenderer(), + uiSettings: coreStart.uiSettings, }, params.element ); diff --git a/examples/dashboard_embeddable_examples/tsconfig.json b/examples/dashboard_embeddable_examples/tsconfig.json index 1c10d59de561f..f17d3ae29f8e7 100644 --- a/examples/dashboard_embeddable_examples/tsconfig.json +++ b/examples/dashboard_embeddable_examples/tsconfig.json @@ -15,7 +15,7 @@ { "path": "../../src/core/tsconfig.json" }, { "path": "../../src/plugins/dashboard/tsconfig.json" }, { "path": "../../src/plugins/embeddable/tsconfig.json" }, - { "path": "../../src/plugins/es_ui_shared/tsconfig.json" }, + { "path": "../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../embeddable_examples/tsconfig.json" }, { "path": "../developer_examples/tsconfig.json" }, ] diff --git a/package.json b/package.json index 16422e3fda27e..f526f357ff347 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "**/pdfkit/crypto-js": "4.0.0", "**/react-syntax-highlighter": "^15.3.1", "**/react-syntax-highlighter/**/highlight.js": "^10.4.1", - "**/refractor/prismjs": "~1.25.0", "**/trim": "1.0.1", "**/typescript": "4.1.3", "**/underscore": "^1.13.1" @@ -102,8 +101,8 @@ "@elastic/charts": "37.0.0", "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.21", - "@elastic/ems-client": "7.15.0", - "@elastic/eui": "38.0.1", + "@elastic/ems-client": "7.16.0", + "@elastic/eui": "39.0.0", "@elastic/filesaver": "1.1.2", "@elastic/maki": "6.3.0", "@elastic/node-crypto": "1.2.1", @@ -184,7 +183,7 @@ "@types/redux-logger": "^3.0.8", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", - "abortcontroller-polyfill": "^1.4.0", + "abortcontroller-polyfill": "^1.7.3", "angular": "^1.8.0", "angular-aria": "^1.8.0", "angular-recursion": "^1.0.5", @@ -209,7 +208,7 @@ "constate": "^1.3.2", "content-disposition": "0.5.3", "copy-to-clipboard": "^3.0.8", - "core-js": "^3.6.5", + "core-js": "^3.18.3", "cronstrue": "^1.51.0", "cytoscape": "^3.10.0", "cytoscape-dagre": "^2.2.2", @@ -369,7 +368,7 @@ "remark-stringify": "^9.0.0", "require-in-the-middle": "^5.1.0", "reselect": "^4.0.0", - "resize-observer-polyfill": "^1.5.0", + "resize-observer-polyfill": "^1.5.1", "rison-node": "1.0.2", "rxjs": "^6.5.5", "safe-squel": "^5.12.5", diff --git a/packages/elastic-apm-generator/src/index.ts b/packages/elastic-apm-generator/src/index.ts index fd83ce483ad4f..7007e92012a66 100644 --- a/packages/elastic-apm-generator/src/index.ts +++ b/packages/elastic-apm-generator/src/index.ts @@ -12,3 +12,4 @@ export { getTransactionMetrics } from './lib/utils/get_transaction_metrics'; export { getSpanDestinationMetrics } from './lib/utils/get_span_destination_metrics'; export { getObserverDefaults } from './lib/defaults/get_observer_defaults'; export { toElasticsearchOutput } from './lib/output/to_elasticsearch_output'; +export { getBreakdownMetrics } from './lib/utils/get_breakdown_metrics'; diff --git a/packages/elastic-apm-generator/src/lib/base_span.ts b/packages/elastic-apm-generator/src/lib/base_span.ts index 24a51282687f4..6288c16d339b6 100644 --- a/packages/elastic-apm-generator/src/lib/base_span.ts +++ b/packages/elastic-apm-generator/src/lib/base_span.ts @@ -8,10 +8,12 @@ import { Fields } from './entity'; import { Serializable } from './serializable'; +import { Span } from './span'; +import { Transaction } from './transaction'; import { generateTraceId } from './utils/generate_id'; export class BaseSpan extends Serializable { - private _children: BaseSpan[] = []; + private readonly _children: BaseSpan[] = []; constructor(fields: Fields) { super({ @@ -22,20 +24,29 @@ export class BaseSpan extends Serializable { }); } - traceId(traceId: string) { - this.fields['trace.id'] = traceId; + parent(span: BaseSpan) { + this.fields['trace.id'] = span.fields['trace.id']; + this.fields['parent.id'] = span.isSpan() + ? span.fields['span.id'] + : span.fields['transaction.id']; + + if (this.isSpan()) { + this.fields['transaction.id'] = span.fields['transaction.id']; + } this._children.forEach((child) => { - child.fields['trace.id'] = traceId; + child.parent(this); }); + return this; } children(...children: BaseSpan[]) { - this._children.push(...children); children.forEach((child) => { - child.traceId(this.fields['trace.id']!); + child.parent(this); }); + this._children.push(...children); + return this; } @@ -52,4 +63,12 @@ export class BaseSpan extends Serializable { serialize(): Fields[] { return [this.fields, ...this._children.flatMap((child) => child.serialize())]; } + + isSpan(): this is Span { + return this.fields['processor.event'] === 'span'; + } + + isTransaction(): this is Transaction { + return this.fields['processor.event'] === 'transaction'; + } } diff --git a/packages/elastic-apm-generator/src/lib/entity.ts b/packages/elastic-apm-generator/src/lib/entity.ts index e0a048c876213..2a4beee652cf7 100644 --- a/packages/elastic-apm-generator/src/lib/entity.ts +++ b/packages/elastic-apm-generator/src/lib/entity.ts @@ -10,9 +10,11 @@ export type Fields = Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; + 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; + 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; @@ -42,6 +44,8 @@ export type Fields = Partial<{ 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; + 'span.self_time.count': number; + 'span.self_time.sum.us': number; }>; export class Entity { diff --git a/packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts b/packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts index ded94f9ad2276..b4cae1b41b9a6 100644 --- a/packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts +++ b/packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts @@ -14,10 +14,12 @@ export function toElasticsearchOutput(events: Fields[], versionOverride?: string return events.map((event) => { const values = { ...event, + ...getObserverDefaults(), '@timestamp': new Date(event['@timestamp']!).toISOString(), 'timestamp.us': event['@timestamp']! * 1000, 'ecs.version': '1.4', - ...getObserverDefaults(), + 'service.node.name': + event['service.node.name'] || event['container.id'] || event['host.name'], }; const document = {}; diff --git a/packages/elastic-apm-generator/src/lib/service.ts b/packages/elastic-apm-generator/src/lib/service.ts index 8ddbd827e842e..859afa18aab03 100644 --- a/packages/elastic-apm-generator/src/lib/service.ts +++ b/packages/elastic-apm-generator/src/lib/service.ts @@ -14,6 +14,7 @@ export class Service extends Entity { return new Instance({ ...this.fields, ['service.node.name']: instanceName, + 'container.id': instanceName, }); } } diff --git a/packages/elastic-apm-generator/src/lib/span.ts b/packages/elastic-apm-generator/src/lib/span.ts index da9ba9cdff722..36f7f44816d01 100644 --- a/packages/elastic-apm-generator/src/lib/span.ts +++ b/packages/elastic-apm-generator/src/lib/span.ts @@ -19,18 +19,6 @@ export class Span extends BaseSpan { }); } - children(...children: BaseSpan[]) { - super.children(...children); - - children.forEach((child) => - child.defaults({ - 'parent.id': this.fields['span.id'], - }) - ); - - return this; - } - duration(duration: number) { this.fields['span.duration.us'] = duration * 1000; return this; diff --git a/packages/elastic-apm-generator/src/lib/transaction.ts b/packages/elastic-apm-generator/src/lib/transaction.ts index 14ed6ac1ea85e..f615f46710996 100644 --- a/packages/elastic-apm-generator/src/lib/transaction.ts +++ b/packages/elastic-apm-generator/src/lib/transaction.ts @@ -11,6 +11,8 @@ import { Fields } from './entity'; import { generateEventId } from './utils/generate_id'; export class Transaction extends BaseSpan { + private _sampled: boolean = true; + constructor(fields: Fields) { super({ ...fields, @@ -19,19 +21,25 @@ export class Transaction extends BaseSpan { 'transaction.sampled': true, }); } - children(...children: BaseSpan[]) { - super.children(...children); - children.forEach((child) => - child.defaults({ - 'transaction.id': this.fields['transaction.id'], - 'parent.id': this.fields['transaction.id'], - }) - ); - return this; - } duration(duration: number) { this.fields['transaction.duration.us'] = duration * 1000; return this; } + + sample(sampled: boolean = true) { + this._sampled = sampled; + return this; + } + + serialize() { + const [transaction, ...spans] = super.serialize(); + + const events = [transaction]; + if (this._sampled) { + events.push(...spans); + } + + return events; + } } diff --git a/packages/elastic-apm-generator/src/lib/utils/aggregate.ts b/packages/elastic-apm-generator/src/lib/utils/aggregate.ts new file mode 100644 index 0000000000000..81b72f6fa01e9 --- /dev/null +++ b/packages/elastic-apm-generator/src/lib/utils/aggregate.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 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 moment from 'moment'; +import { pickBy } from 'lodash'; +import objectHash from 'object-hash'; +import { Fields } from '../entity'; +import { createPicker } from './create_picker'; + +export function aggregate(events: Fields[], fields: string[]) { + const picker = createPicker(fields); + + const metricsets = new Map<string, { key: Fields; events: Fields[] }>(); + + function getMetricsetKey(span: Fields) { + const timestamp = moment(span['@timestamp']).valueOf(); + return { + '@timestamp': timestamp - (timestamp % (60 * 1000)), + ...pickBy(span, picker), + }; + } + + for (const event of events) { + const key = getMetricsetKey(event); + const id = objectHash(key); + + let metricset = metricsets.get(id); + + if (!metricset) { + metricset = { + key: { ...key, 'processor.event': 'metric', 'processor.name': 'metric' }, + events: [], + }; + metricsets.set(id, metricset); + } + + metricset.events.push(event); + } + + return Array.from(metricsets.values()); +} diff --git a/packages/elastic-apm-generator/src/lib/utils/create_picker.ts b/packages/elastic-apm-generator/src/lib/utils/create_picker.ts new file mode 100644 index 0000000000000..7fce23b6fc966 --- /dev/null +++ b/packages/elastic-apm-generator/src/lib/utils/create_picker.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 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 function createPicker(fields: string[]) { + const wildcards = fields + .filter((field) => field.endsWith('.*')) + .map((field) => field.replace('*', '')); + + return (value: unknown, key: string) => { + return fields.includes(key) || wildcards.some((field) => key.startsWith(field)); + }; +} diff --git a/packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts b/packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts new file mode 100644 index 0000000000000..8eae0941c6bdd --- /dev/null +++ b/packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.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 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 objectHash from 'object-hash'; +import { groupBy, pickBy } from 'lodash'; +import { Fields } from '../entity'; +import { createPicker } from './create_picker'; + +const instanceFields = [ + 'container.*', + 'kubernetes.*', + 'agent.*', + 'process.*', + 'cloud.*', + 'service.*', + 'host.*', +]; + +const instancePicker = createPicker(instanceFields); + +const metricsetPicker = createPicker([ + 'transaction.type', + 'transaction.name', + 'span.type', + 'span.subtype', +]); + +export function getBreakdownMetrics(events: Fields[]) { + const txWithSpans = groupBy( + events.filter( + (event) => event['processor.event'] === 'span' || event['processor.event'] === 'transaction' + ), + (event) => event['transaction.id'] + ); + + const metricsets: Map<string, Fields> = new Map(); + + Object.keys(txWithSpans).forEach((transactionId) => { + const txEvents = txWithSpans[transactionId]; + const transaction = txEvents.find((event) => event['processor.event'] === 'transaction')!; + + const eventsById: Record<string, Fields> = {}; + const activityByParentId: Record<string, Array<{ from: number; to: number }>> = {}; + for (const event of txEvents) { + const id = + event['processor.event'] === 'transaction' ? event['transaction.id'] : event['span.id']; + eventsById[id!] = event; + + const parentId = event['parent.id']; + + if (!parentId) { + continue; + } + + if (!activityByParentId[parentId]) { + activityByParentId[parentId] = []; + } + + const from = event['@timestamp']! * 1000; + const to = + from + + (event['processor.event'] === 'transaction' + ? event['transaction.duration.us']! + : event['span.duration.us']!); + + activityByParentId[parentId].push({ from, to }); + } + + // eslint-disable-next-line guard-for-in + for (const id in eventsById) { + const event = eventsById[id]; + const activities = activityByParentId[id] || []; + + const timeStart = event['@timestamp']! * 1000; + + let selfTime = 0; + let lastMeasurement = timeStart; + const changeTimestamps = [ + ...new Set([ + timeStart, + ...activities.flatMap((activity) => [activity.from, activity.to]), + timeStart + + (event['processor.event'] === 'transaction' + ? event['transaction.duration.us']! + : event['span.duration.us']!), + ]), + ]; + + for (const timestamp of changeTimestamps) { + const hasActiveChildren = activities.some( + (activity) => activity.from < timestamp && activity.to >= timestamp + ); + + if (!hasActiveChildren) { + selfTime += timestamp - lastMeasurement; + } + + lastMeasurement = timestamp; + } + + const key = { + '@timestamp': event['@timestamp']! - (event['@timestamp']! % (30 * 1000)), + 'transaction.type': transaction['transaction.type'], + 'transaction.name': transaction['transaction.name'], + ...pickBy(event, metricsetPicker), + }; + + const instance = pickBy(event, instancePicker); + + const metricsetId = objectHash(key); + + let metricset = metricsets.get(metricsetId); + + if (!metricset) { + metricset = { + ...key, + ...instance, + 'processor.event': 'metric', + 'processor.name': 'metric', + 'metricset.name': `span_breakdown`, + 'span.self_time.count': 0, + 'span.self_time.sum.us': 0, + }; + + if (event['processor.event'] === 'transaction') { + metricset['span.type'] = 'app'; + } else { + metricset['span.type'] = event['span.type']; + metricset['span.subtype'] = event['span.subtype']; + } + + metricsets.set(metricsetId, metricset); + } + + metricset['span.self_time.count']!++; + metricset['span.self_time.sum.us']! += selfTime; + } + }); + + return Array.from(metricsets.values()); +} diff --git a/packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts b/packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts index 3740ad685735e..decf2f71a9be4 100644 --- a/packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts +++ b/packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts @@ -6,46 +6,34 @@ * Side Public License, v 1. */ -import { pick } from 'lodash'; -import moment from 'moment'; -import objectHash from 'object-hash'; import { Fields } from '../entity'; +import { aggregate } from './aggregate'; export function getSpanDestinationMetrics(events: Fields[]) { const exitSpans = events.filter((event) => !!event['span.destination.service.resource']); - const metricsets = new Map<string, Fields>(); + const metricsets = aggregate(exitSpans, [ + 'event.outcome', + 'agent.name', + 'service.environment', + 'service.name', + 'span.destination.service.resource', + ]); - function getSpanBucketKey(span: Fields) { - return { - '@timestamp': moment(span['@timestamp']).startOf('minute').valueOf(), - ...pick(span, [ - 'event.outcome', - 'agent.name', - 'service.environment', - 'service.name', - 'span.destination.service.resource', - ]), - }; - } - - for (const span of exitSpans) { - const key = getSpanBucketKey(span); - const id = objectHash(key); + return metricsets.map((metricset) => { + let count = 0; + let sum = 0; - let metricset = metricsets.get(id); - if (!metricset) { - metricset = { - ['processor.event']: 'metric', - ...key, - 'span.destination.service.response_time.sum.us': 0, - 'span.destination.service.response_time.count': 0, - }; - metricsets.set(id, metricset); + for (const event of metricset.events) { + count++; + sum += event['span.duration.us']!; } - metricset['span.destination.service.response_time.count']! += 1; - metricset['span.destination.service.response_time.sum.us']! += span['span.duration.us']!; - } - return [...Array.from(metricsets.values())]; + return { + ...metricset.key, + ['metricset.name']: 'span_destination', + 'span.destination.service.response_time.sum.us': sum, + 'span.destination.service.response_time.count': count, + }; + }); } diff --git a/packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts b/packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts index 62ecb9e20006f..4d46461c6dcc9 100644 --- a/packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts +++ b/packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts @@ -6,10 +6,9 @@ * Side Public License, v 1. */ -import { pick, sortBy } from 'lodash'; -import moment from 'moment'; -import objectHash from 'object-hash'; +import { sortBy } from 'lodash'; import { Fields } from '../entity'; +import { aggregate } from './aggregate'; function sortAndCompressHistogram(histogram?: { values: number[]; counts: number[] }) { return sortBy(histogram?.values).reduce( @@ -30,60 +29,45 @@ function sortAndCompressHistogram(histogram?: { values: number[]; counts: number } export function getTransactionMetrics(events: Fields[]) { - const transactions = events.filter((event) => event['processor.event'] === 'transaction'); + const transactions = events + .filter((event) => event['processor.event'] === 'transaction') + .map((transaction) => { + return { + ...transaction, + ['trace.root']: transaction['parent.id'] === undefined, + }; + }); - const metricsets = new Map<string, Fields>(); + const metricsets = aggregate(transactions, [ + 'trace.root', + 'transaction.name', + 'transaction.type', + 'event.outcome', + 'transaction.result', + 'agent.name', + 'service.environment', + 'service.name', + 'service.version', + 'host.name', + 'container.id', + 'kubernetes.pod.name', + ]); - function getTransactionBucketKey(transaction: Fields) { - return { - '@timestamp': moment(transaction['@timestamp']).startOf('minute').valueOf(), - 'trace.root': transaction['parent.id'] === undefined, - ...pick(transaction, [ - 'transaction.name', - 'transaction.type', - 'event.outcome', - 'transaction.result', - 'agent.name', - 'service.environment', - 'service.name', - 'service.version', - 'host.name', - 'container.id', - 'kubernetes.pod.name', - ]), + return metricsets.map((metricset) => { + const histogram = { + values: [] as number[], + counts: [] as number[], }; - } - for (const transaction of transactions) { - const key = getTransactionBucketKey(transaction); - const id = objectHash(key); - let metricset = metricsets.get(id); - if (!metricset) { - metricset = { - ...key, - ['processor.event']: 'metric', - 'transaction.duration.histogram': { - values: [], - counts: [], - }, - }; - metricsets.set(id, metricset); + for (const transaction of metricset.events) { + histogram.counts.push(1); + histogram.values.push(Number(transaction['transaction.duration.us'])); } - metricset['transaction.duration.histogram']?.counts.push(1); - metricset['transaction.duration.histogram']?.values.push( - Number(transaction['transaction.duration.us']) - ); - } - return [ - ...Array.from(metricsets.values()).map((metricset) => { - return { - ...metricset, - ['transaction.duration.histogram']: sortAndCompressHistogram( - metricset['transaction.duration.histogram'] - ), - _doc_count: metricset['transaction.duration.histogram']!.values.length, - }; - }), - ]; + return { + ...metricset.key, + 'transaction.duration.histogram': sortAndCompressHistogram(histogram), + _doc_count: metricset.events.length, + }; + }); } diff --git a/packages/elastic-apm-generator/src/scripts/examples/01_simple_trace.ts b/packages/elastic-apm-generator/src/scripts/examples/01_simple_trace.ts index eef3e6cc40560..7aae2986919c8 100644 --- a/packages/elastic-apm-generator/src/scripts/examples/01_simple_trace.ts +++ b/packages/elastic-apm-generator/src/scripts/examples/01_simple_trace.ts @@ -7,17 +7,18 @@ */ import { service, timerange, getTransactionMetrics, getSpanDestinationMetrics } from '../..'; +import { getBreakdownMetrics } from '../../lib/utils/get_breakdown_metrics'; export function simpleTrace(from: number, to: number) { const instance = service('opbeans-go', 'production', 'go').instance('instance'); const range = timerange(from, to); - const transactionName = '100rpm (75% success) failed 1000ms'; + const transactionName = '100rpm (80% success) failed 1000ms'; const successfulTraceEvents = range - .interval('1m') - .rate(75) + .interval('30s') + .rate(40) .flatMap((timestamp) => instance .transaction(transactionName) @@ -31,14 +32,14 @@ export function simpleTrace(from: number, to: number) { .success() .destination('elasticsearch') .timestamp(timestamp), - instance.span('custom_operation', 'app').duration(50).success().timestamp(timestamp) + instance.span('custom_operation', 'custom').duration(100).success().timestamp(timestamp) ) .serialize() ); const failedTraceEvents = range - .interval('1m') - .rate(25) + .interval('30s') + .rate(10) .flatMap((timestamp) => instance .transaction(transactionName) @@ -50,5 +51,10 @@ export function simpleTrace(from: number, to: number) { const events = successfulTraceEvents.concat(failedTraceEvents); - return events.concat(getTransactionMetrics(events)).concat(getSpanDestinationMetrics(events)); + return [ + ...events, + ...getTransactionMetrics(events), + ...getSpanDestinationMetrics(events), + ...getBreakdownMetrics(events), + ]; } diff --git a/packages/elastic-apm-generator/src/test/scenarios/01_simple_trace.test.ts b/packages/elastic-apm-generator/src/test/scenarios/01_simple_trace.test.ts index 6bae70507dcbe..733093ce0a71c 100644 --- a/packages/elastic-apm-generator/src/test/scenarios/01_simple_trace.test.ts +++ b/packages/elastic-apm-generator/src/test/scenarios/01_simple_trace.test.ts @@ -68,6 +68,7 @@ describe('simple trace', () => { expect(transaction).toEqual({ '@timestamp': 1609459200000, 'agent.name': 'java', + 'container.id': 'instance-1', 'event.outcome': 'success', 'processor.event': 'transaction', 'processor.name': 'transaction', @@ -89,6 +90,7 @@ describe('simple trace', () => { expect(span).toEqual({ '@timestamp': 1609459200050, 'agent.name': 'java', + 'container.id': 'instance-1', 'event.outcome': 'success', 'parent.id': 'e7433020f2745625', 'processor.event': 'span', diff --git a/packages/elastic-apm-generator/src/test/scenarios/04_breakdown_metrics.test.ts b/packages/elastic-apm-generator/src/test/scenarios/04_breakdown_metrics.test.ts new file mode 100644 index 0000000000000..aeb944f35faf6 --- /dev/null +++ b/packages/elastic-apm-generator/src/test/scenarios/04_breakdown_metrics.test.ts @@ -0,0 +1,105 @@ +/* + * Copyright 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 { sumBy } from 'lodash'; +import { Fields } from '../../lib/entity'; +import { service } from '../../lib/service'; +import { timerange } from '../../lib/timerange'; +import { getBreakdownMetrics } from '../../lib/utils/get_breakdown_metrics'; + +describe('breakdown metrics', () => { + let events: Fields[]; + + const LIST_RATE = 2; + const LIST_SPANS = 2; + const ID_RATE = 4; + const ID_SPANS = 2; + const INTERVALS = 6; + + beforeEach(() => { + const javaService = service('opbeans-java', 'production', 'java'); + const javaInstance = javaService.instance('instance-1'); + + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + + const range = timerange(start, start + INTERVALS * 30 * 1000 - 1); + + events = getBreakdownMetrics([ + ...range + .interval('30s') + .rate(LIST_RATE) + .flatMap((timestamp) => + javaInstance + .transaction('GET /api/product/list') + .timestamp(timestamp) + .duration(1000) + .children( + javaInstance + .span('GET apm-*/_search', 'db', 'elasticsearch') + .timestamp(timestamp + 150) + .duration(500), + javaInstance.span('GET foo', 'db', 'redis').timestamp(timestamp).duration(100) + ) + .serialize() + ), + ...range + .interval('30s') + .rate(ID_RATE) + .flatMap((timestamp) => + javaInstance + .transaction('GET /api/product/:id') + .timestamp(timestamp) + .duration(1000) + .children( + javaInstance + .span('GET apm-*/_search', 'db', 'elasticsearch') + .duration(500) + .timestamp(timestamp + 100) + .children( + javaInstance + .span('bar', 'external', 'http') + .timestamp(timestamp + 200) + .duration(100) + ) + ) + .serialize() + ), + ]).filter((event) => event['processor.event'] === 'metric'); + }); + + it('generates the right amount of breakdown metrics', () => { + expect(events.length).toBe(INTERVALS * (LIST_SPANS + 1 + ID_SPANS + 1)); + }); + + it('calculates breakdown metrics for the right amount of transactions and spans', () => { + expect(sumBy(events, (event) => event['span.self_time.count']!)).toBe( + INTERVALS * LIST_RATE * (LIST_SPANS + 1) + INTERVALS * ID_RATE * (ID_SPANS + 1) + ); + }); + + it('generates app metricsets for transaction self time', () => { + expect(events.some((event) => event['span.type'] === 'app' && !event['span.subtype'])).toBe( + true + ); + }); + + it('generates the right statistic', () => { + const elasticsearchSets = events.filter((event) => event['span.subtype'] === 'elasticsearch'); + + const expectedCountFromListTransaction = INTERVALS * LIST_RATE; + + const expectedCountFromIdTransaction = INTERVALS * ID_RATE; + + const expectedCount = expectedCountFromIdTransaction + expectedCountFromListTransaction; + + expect(sumBy(elasticsearchSets, (set) => set['span.self_time.count']!)).toBe(expectedCount); + + expect(sumBy(elasticsearchSets, (set) => set['span.self_time.sum.us']!)).toBe( + expectedCountFromListTransaction * 500 * 1000 + expectedCountFromIdTransaction * 400 * 1000 + ); + }); +}); diff --git a/packages/elastic-apm-generator/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap b/packages/elastic-apm-generator/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap index 6eec0ce38ba30..00a55cb87b125 100644 --- a/packages/elastic-apm-generator/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap +++ b/packages/elastic-apm-generator/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap @@ -5,6 +5,7 @@ Array [ Object { "@timestamp": 1609459200000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -21,6 +22,7 @@ Array [ Object { "@timestamp": 1609459200050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "36c16f18e75058f8", "processor.event": "span", @@ -39,6 +41,7 @@ Array [ Object { "@timestamp": 1609459260000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -55,6 +58,7 @@ Array [ Object { "@timestamp": 1609459260050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "65ce74106eb050be", "processor.event": "span", @@ -73,6 +77,7 @@ Array [ Object { "@timestamp": 1609459320000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -89,6 +94,7 @@ Array [ Object { "@timestamp": 1609459320050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "91fa709d90625fff", "processor.event": "span", @@ -107,6 +113,7 @@ Array [ Object { "@timestamp": 1609459380000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -123,6 +130,7 @@ Array [ Object { "@timestamp": 1609459380050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "6c500d1d19835e68", "processor.event": "span", @@ -141,6 +149,7 @@ Array [ Object { "@timestamp": 1609459440000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -157,6 +166,7 @@ Array [ Object { "@timestamp": 1609459440050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "1b3246cc83595869", "processor.event": "span", @@ -175,6 +185,7 @@ Array [ Object { "@timestamp": 1609459500000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -191,6 +202,7 @@ Array [ Object { "@timestamp": 1609459500050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "12b49e3c83fe58d5", "processor.event": "span", @@ -209,6 +221,7 @@ Array [ Object { "@timestamp": 1609459560000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -225,6 +238,7 @@ Array [ Object { "@timestamp": 1609459560050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "d9272009dd4354a1", "processor.event": "span", @@ -243,6 +257,7 @@ Array [ Object { "@timestamp": 1609459620000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -259,6 +274,7 @@ Array [ Object { "@timestamp": 1609459620050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "bc52ca08063c505b", "processor.event": "span", @@ -277,6 +293,7 @@ Array [ Object { "@timestamp": 1609459680000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -293,6 +310,7 @@ Array [ Object { "@timestamp": 1609459680050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "186858dd88b75d59", "processor.event": "span", @@ -311,6 +329,7 @@ Array [ Object { "@timestamp": 1609459740000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -327,6 +346,7 @@ Array [ Object { "@timestamp": 1609459740050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "0d5f44d48189546c", "processor.event": "span", @@ -345,6 +365,7 @@ Array [ Object { "@timestamp": 1609459800000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -361,6 +382,7 @@ Array [ Object { "@timestamp": 1609459800050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "7483e0606e435c83", "processor.event": "span", @@ -379,6 +401,7 @@ Array [ Object { "@timestamp": 1609459860000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -395,6 +418,7 @@ Array [ Object { "@timestamp": 1609459860050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "f142c4cbc7f3568e", "processor.event": "span", @@ -413,6 +437,7 @@ Array [ Object { "@timestamp": 1609459920000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -429,6 +454,7 @@ Array [ Object { "@timestamp": 1609459920050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "2e3a47fa2d905519", "processor.event": "span", @@ -447,6 +473,7 @@ Array [ Object { "@timestamp": 1609459980000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -463,6 +490,7 @@ Array [ Object { "@timestamp": 1609459980050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "de5eaa1e47dc56b1", "processor.event": "span", @@ -481,6 +509,7 @@ Array [ Object { "@timestamp": 1609460040000, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "processor.event": "transaction", "processor.name": "transaction", @@ -497,6 +526,7 @@ Array [ Object { "@timestamp": 1609460040050, "agent.name": "java", + "container.id": "instance-1", "event.outcome": "success", "parent.id": "af7eac7ae61e576a", "processor.event": "span", diff --git a/packages/kbn-apm-config-loader/src/config.test.ts b/packages/kbn-apm-config-loader/src/config.test.ts index 4e4dbf81740b3..60d773e3a420b 100644 --- a/packages/kbn-apm-config-loader/src/config.test.ts +++ b/packages/kbn-apm-config-loader/src/config.test.ts @@ -94,8 +94,8 @@ describe('ApmConfiguration', () => { "globalLabels": Object {}, "logUncaughtExceptions": true, "metricsInterval": "30s", - "secretToken": "ZQHYvrmXEx04ozge8F", - "serverUrl": "https://38b80fbd79fb4c91bae06b4642d4d093.apm.us-east-1.aws.cloud.es.io", + "secretToken": "7YKhoXsO4MzjhXjx2c", + "serverUrl": "https://kibana-ci-apm.apm.us-central1.gcp.cloud.es.io", "serviceName": "serviceName", "serviceVersion": "8.0.0", "transactionSampleRate": 1, @@ -117,8 +117,8 @@ describe('ApmConfiguration', () => { }, "logUncaughtExceptions": true, "metricsInterval": "120s", - "secretToken": "ZQHYvrmXEx04ozge8F", - "serverUrl": "https://38b80fbd79fb4c91bae06b4642d4d093.apm.us-east-1.aws.cloud.es.io", + "secretToken": "7YKhoXsO4MzjhXjx2c", + "serverUrl": "https://kibana-ci-apm.apm.us-central1.gcp.cloud.es.io", "serviceName": "serviceName", "serviceVersion": "8.0.0", "transactionSampleRate": 1, diff --git a/packages/kbn-apm-config-loader/src/config.ts b/packages/kbn-apm-config-loader/src/config.ts index ad2fd63f0fec4..999e4ce3a6805 100644 --- a/packages/kbn-apm-config-loader/src/config.ts +++ b/packages/kbn-apm-config-loader/src/config.ts @@ -23,14 +23,14 @@ const DEFAULT_CONFIG: AgentConfigOptions = { }; const CENTRALIZED_SERVICE_BASE_CONFIG: AgentConfigOptions = { - serverUrl: 'https://38b80fbd79fb4c91bae06b4642d4d093.apm.us-east-1.aws.cloud.es.io', + serverUrl: 'https://kibana-ci-apm.apm.us-central1.gcp.cloud.es.io', // The secretToken below is intended to be hardcoded in this file even though // it makes it public. This is not a security/privacy issue. Normally we'd // instead disable the need for a secretToken in the APM Server config where // the data is transmitted to, but due to how it's being hosted, it's easier, // for now, to simply leave it in. - secretToken: 'ZQHYvrmXEx04ozge8F', + secretToken: '7YKhoXsO4MzjhXjx2c', centralConfig: false, metricsInterval: '30s', diff --git a/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts b/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts index 9af52ae8d2df0..f73b9c830a2ab 100644 --- a/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts +++ b/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts @@ -8,8 +8,18 @@ import type { ToolingLog } from '../tooling_log'; +/** + * Information about how CiStatsReporter should talk to the ci-stats service. Normally + * it is read from a JSON environment variable using the `parseConfig()` function + * exported by this module. + */ export interface Config { + /** ApiToken necessary for writing build data to ci-stats service */ apiToken: string; + /** + * uuid which should be obtained by first creating a build with the + * ci-stats service and then passing it to all subsequent steps + */ buildId: string; } diff --git a/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts b/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts index 05f54e8d38c8c..3dff5acdc228a 100644 --- a/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts +++ b/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts @@ -130,7 +130,7 @@ export class CiStatsReporter { } try { - const { stdout } = await execa('git', ['branch', '--show-current']); + const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD']); branch = stdout; } catch (e) { this.log.debug(e.message); diff --git a/packages/kbn-dev-utils/src/ci_stats_reporter/index.ts b/packages/kbn-dev-utils/src/ci_stats_reporter/index.ts index 9cb05608526eb..318a2921517f1 100644 --- a/packages/kbn-dev-utils/src/ci_stats_reporter/index.ts +++ b/packages/kbn-dev-utils/src/ci_stats_reporter/index.ts @@ -7,5 +7,6 @@ */ export * from './ci_stats_reporter'; +export type { Config } from './ci_stats_config'; export * from './ship_ci_stats_cli'; export { getTimeReporter } from './report_time'; diff --git a/packages/kbn-dev-utils/src/proc_runner/proc_runner.ts b/packages/kbn-dev-utils/src/proc_runner/proc_runner.ts index 35c910c911105..8ef32411621f8 100644 --- a/packages/kbn-dev-utils/src/proc_runner/proc_runner.ts +++ b/packages/kbn-dev-utils/src/proc_runner/proc_runner.ts @@ -37,6 +37,8 @@ export class ProcRunner { private signalUnsubscribe: () => void; constructor(private log: ToolingLog) { + this.log = log.withType('ProcRunner'); + this.signalUnsubscribe = exitHook(() => { this.teardown().catch((error) => { log.error(`ProcRunner teardown error: ${error.stack}`); diff --git a/packages/kbn-dev-utils/src/run/cleanup.ts b/packages/kbn-dev-utils/src/run/cleanup.ts index 26a6f5c632c46..ba0b762a562ad 100644 --- a/packages/kbn-dev-utils/src/run/cleanup.ts +++ b/packages/kbn-dev-utils/src/run/cleanup.ts @@ -13,6 +13,10 @@ import exitHook from 'exit-hook'; import { ToolingLog } from '../tooling_log'; import { isFailError } from './fail'; +/** + * A function which will be called when the CLI is torn-down which should + * quickly cleanup whatever it needs. + */ export type CleanupTask = () => void; export class Cleanup { diff --git a/packages/kbn-dev-utils/src/run/index.ts b/packages/kbn-dev-utils/src/run/index.ts index f3c364c774d30..505ef4ee264d6 100644 --- a/packages/kbn-dev-utils/src/run/index.ts +++ b/packages/kbn-dev-utils/src/run/index.ts @@ -10,3 +10,4 @@ export * from './run'; export * from './run_with_commands'; export * from './flags'; export * from './fail'; +export type { CleanupTask } from './cleanup'; diff --git a/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log.test.ts.snap b/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log.test.ts.snap index 059e3d49c3688..7742c2bb681d0 100644 --- a/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log.test.ts.snap +++ b/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log.test.ts.snap @@ -10,6 +10,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "debug", }, ], @@ -24,6 +25,7 @@ Array [ [Error: error message], ], "indent": 0, + "source": undefined, "type": "error", }, ], @@ -33,6 +35,7 @@ Array [ "string message", ], "indent": 0, + "source": undefined, "type": "error", }, ], @@ -50,6 +53,7 @@ Array [ "foo", ], "indent": 0, + "source": undefined, "type": "debug", }, Object { @@ -57,6 +61,7 @@ Array [ "bar", ], "indent": 0, + "source": undefined, "type": "info", }, Object { @@ -64,6 +69,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "verbose", }, ] @@ -76,6 +82,7 @@ Array [ "foo", ], "indent": 0, + "source": undefined, "type": "debug", }, Object { @@ -83,6 +90,7 @@ Array [ "bar", ], "indent": 0, + "source": undefined, "type": "info", }, Object { @@ -90,6 +98,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "verbose", }, ] @@ -103,6 +112,7 @@ Array [ "foo", ], "indent": 1, + "source": undefined, "type": "debug", }, ], @@ -112,6 +122,7 @@ Array [ "bar", ], "indent": 3, + "source": undefined, "type": "debug", }, ], @@ -121,6 +132,7 @@ Array [ "baz", ], "indent": 6, + "source": undefined, "type": "debug", }, ], @@ -130,6 +142,7 @@ Array [ "box", ], "indent": 4, + "source": undefined, "type": "debug", }, ], @@ -139,6 +152,7 @@ Array [ "foo", ], "indent": 0, + "source": undefined, "type": "debug", }, ], @@ -155,6 +169,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "info", }, ], @@ -171,6 +186,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "success", }, ], @@ -187,6 +203,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "verbose", }, ], @@ -203,6 +220,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "warning", }, ], @@ -219,6 +237,7 @@ Array [ "baz", ], "indent": 0, + "source": undefined, "type": "write", }, ], diff --git a/packages/kbn-dev-utils/src/tooling_log/index.ts b/packages/kbn-dev-utils/src/tooling_log/index.ts index 65dcd3054ef93..4da54ee9bfeae 100644 --- a/packages/kbn-dev-utils/src/tooling_log/index.ts +++ b/packages/kbn-dev-utils/src/tooling_log/index.ts @@ -7,6 +7,9 @@ */ export { ToolingLog } from './tooling_log'; +export type { ToolingLogOptions } from './tooling_log'; export { ToolingLogTextWriter, ToolingLogTextWriterConfig } from './tooling_log_text_writer'; export { pickLevelFromFlags, parseLogLevel, LogLevel, ParsedLogLevel } from './log_levels'; export { ToolingLogCollectingWriter } from './tooling_log_collecting_writer'; +export type { Writer } from './writer'; +export type { Message } from './message'; diff --git a/packages/kbn-dev-utils/src/tooling_log/message.ts b/packages/kbn-dev-utils/src/tooling_log/message.ts index ebd3a255a73a4..082c0e65d48b2 100644 --- a/packages/kbn-dev-utils/src/tooling_log/message.ts +++ b/packages/kbn-dev-utils/src/tooling_log/message.ts @@ -8,8 +8,16 @@ export type MessageTypes = 'verbose' | 'debug' | 'info' | 'success' | 'warning' | 'error' | 'write'; +/** + * The object shape passed to ToolingLog writers each time the log is used. + */ export interface Message { + /** level/type of message */ type: MessageTypes; + /** indentation intended when message written to a text log */ indent: number; + /** type of logger this message came from */ + source?: string; + /** args passed to the logging method */ args: any[]; } diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts index ec63a9fb7e6f2..506f89786917f 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts @@ -155,3 +155,40 @@ describe('#getWritten$()', () => { await testWrittenMsgs([{ write: jest.fn(() => false) }, { write: jest.fn(() => false) }]); }); }); + +describe('#withType()', () => { + it('creates a child logger with a unique type that respects all other settings', () => { + const writerA = new ToolingLogCollectingWriter(); + const writerB = new ToolingLogCollectingWriter(); + const log = new ToolingLog(); + log.setWriters([writerA]); + + const fork = log.withType('someType'); + log.info('hello'); + fork.info('world'); + fork.indent(2); + log.debug('indented'); + fork.indent(-2); + log.debug('not-indented'); + + log.setWriters([writerB]); + fork.info('to new writer'); + fork.indent(5); + log.info('also to new writer'); + + expect(writerA.messages).toMatchInlineSnapshot(` + Array [ + " info hello", + " info source[someType] world", + " │ debg indented", + " debg not-indented", + ] + `); + expect(writerB.messages).toMatchInlineSnapshot(` + Array [ + " info source[someType] to new writer", + " │ info also to new writer", + ] + `); + }); +}); diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log.ts index e9fd15afefe4e..84e9159dfcd41 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log.ts @@ -12,21 +12,45 @@ import { ToolingLogTextWriter, ToolingLogTextWriterConfig } from './tooling_log_ import { Writer } from './writer'; import { Message, MessageTypes } from './message'; +export interface ToolingLogOptions { + /** + * type name for this logger, will be assigned to the "source" + * properties of messages produced by this logger + */ + type?: string; + /** + * parent ToolingLog. When a ToolingLog has a parent they will both + * share indent and writers state. Changing the indent width or + * writers on either log will update the other too. + */ + parent?: ToolingLog; +} + export class ToolingLog { - private indentWidth = 0; - private writers: Writer[]; + private indentWidth$: Rx.BehaviorSubject<number>; + private writers$: Rx.BehaviorSubject<Writer[]>; private readonly written$: Rx.Subject<Message>; + private readonly type: string | undefined; + + constructor(writerConfig?: ToolingLogTextWriterConfig, options?: ToolingLogOptions) { + this.indentWidth$ = options?.parent ? options.parent.indentWidth$ : new Rx.BehaviorSubject(0); - constructor(writerConfig?: ToolingLogTextWriterConfig) { - this.writers = writerConfig ? [new ToolingLogTextWriter(writerConfig)] : []; - this.written$ = new Rx.Subject(); + this.writers$ = options?.parent + ? options.parent.writers$ + : new Rx.BehaviorSubject<Writer[]>([]); + if (!options?.parent && writerConfig) { + this.writers$.next([new ToolingLogTextWriter(writerConfig)]); + } + + this.written$ = options?.parent ? options.parent.written$ : new Rx.Subject(); + this.type = options?.type; } /** * Get the current indentation level of the ToolingLog */ public getIndent() { - return this.indentWidth; + return this.indentWidth$.getValue(); } /** @@ -39,8 +63,8 @@ export class ToolingLog { * @param block a function to run and reset any indentation changes after */ public indent<T>(delta = 0, block?: () => Promise<T>) { - const originalWidth = this.indentWidth; - this.indentWidth = Math.max(this.indentWidth + delta, 0); + const originalWidth = this.indentWidth$.getValue(); + this.indentWidth$.next(Math.max(originalWidth + delta, 0)); if (!block) { return; } @@ -49,7 +73,7 @@ export class ToolingLog { try { return await block(); } finally { - this.indentWidth = originalWidth; + this.indentWidth$.next(originalWidth); } })(); } @@ -83,26 +107,40 @@ export class ToolingLog { } public getWriters() { - return this.writers.slice(0); + return [...this.writers$.getValue()]; } public setWriters(writers: Writer[]) { - this.writers = [...writers]; + this.writers$.next([...writers]); } public getWritten$() { return this.written$.asObservable(); } + /** + * Create a new ToolingLog which sets a different "type", allowing messages to be filtered out by "source" + * @param type A string that will be passed along with messages from this logger which can be used to filter messages with `ignoreSources` + */ + public withType(type: string) { + return new ToolingLog(undefined, { + type, + parent: this, + }); + } + private sendToWriters(type: MessageTypes, args: any[]) { - const msg = { + const indent = this.indentWidth$.getValue(); + const writers = this.writers$.getValue(); + const msg: Message = { type, - indent: this.indentWidth, + indent, + source: this.type, args, }; let written = false; - for (const writer of this.writers) { + for (const writer of writers) { if (writer.write(msg)) { written = true; } diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts index cc399e40d2cb4..6f73563f4a2c5 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts @@ -8,6 +8,7 @@ import { ToolingLogTextWriter } from './tooling_log_text_writer'; import { LogLevel } from './log_levels'; +import { Message } from './message'; export class ToolingLogCollectingWriter extends ToolingLogTextWriter { messages: string[] = []; @@ -23,4 +24,18 @@ export class ToolingLogCollectingWriter extends ToolingLogTextWriter { }, }); } + + /** + * Called by ToolingLog, extends messages with the source if message includes one. + */ + write(msg: Message) { + if (msg.source) { + return super.write({ + ...msg, + args: [`source[${msg.source}]`, ...msg.args], + }); + } + + return super.write(msg); + } } diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts index 2b1806eb4b9a2..660dae3fa1f55 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts @@ -28,7 +28,20 @@ const MSG_PREFIXES = { const has = <T extends object>(obj: T, key: any): key is keyof T => obj.hasOwnProperty(key); export interface ToolingLogTextWriterConfig { + /** + * Log level, messages below this level will be ignored + */ level: LogLevel; + /** + * List of message sources/ToolingLog types which will be ignored. Create + * a logger with `ToolingLog#withType()` to create messages with a specific + * source. Ignored messages will be dropped without writing. + */ + ignoreSources?: string[]; + /** + * Target which will receive formatted message lines, a common value for `writeTo` + * is process.stdout + */ writeTo: { write(s: string): void; }; @@ -59,10 +72,12 @@ export class ToolingLogTextWriter implements Writer { public readonly writeTo: { write(msg: string): void; }; + private readonly ignoreSources?: string[]; constructor(config: ToolingLogTextWriterConfig) { this.level = parseLogLevel(config.level); this.writeTo = config.writeTo; + this.ignoreSources = config.ignoreSources; if (!this.writeTo || typeof this.writeTo.write !== 'function') { throw new Error( @@ -76,6 +91,10 @@ export class ToolingLogTextWriter implements Writer { return false; } + if (this.ignoreSources && msg.source && this.ignoreSources.includes(msg.source)) { + return false; + } + const prefix = has(MSG_PREFIXES, msg.type) ? MSG_PREFIXES[msg.type] : ''; ToolingLogTextWriter.write(this.writeTo, prefix, msg); return true; diff --git a/packages/kbn-dev-utils/src/tooling_log/writer.ts b/packages/kbn-dev-utils/src/tooling_log/writer.ts index fd56f4fe3d3a6..26fec6a780694 100644 --- a/packages/kbn-dev-utils/src/tooling_log/writer.ts +++ b/packages/kbn-dev-utils/src/tooling_log/writer.ts @@ -8,6 +8,15 @@ import { Message } from './message'; +/** + * An object which received ToolingLog `Messages` and sends them to + * some interface for collecting logs like stdio, or a file + */ export interface Writer { + /** + * Called with every log message, should return true if the message + * was written and false if it was ignored. + * @param msg The log message to write + */ write(msg: Message): boolean; } diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts b/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts index 1f709a52a0fc1..4ef3039253e90 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts @@ -109,30 +109,36 @@ export function runBuildApiDocsCli() { const id = plugin.manifest.id; const pluginApi = pluginApiMap[id]; const pluginStats = allPluginStats[id]; + const pluginTeam = plugin.manifest.owner.name; reporter.metrics([ { id, + meta: { pluginTeam }, group: 'API count', value: pluginStats.apiCount, }, { id, + meta: { pluginTeam }, group: 'API count missing comments', value: pluginStats.missingComments.length, }, { id, + meta: { pluginTeam }, group: 'API count with any type', value: pluginStats.isAnyType.length, }, { id, + meta: { pluginTeam }, group: 'Non-exported public API item count', value: missingApiItems[id] ? Object.keys(missingApiItems[id]).length : 0, }, { id, + meta: { pluginTeam }, group: 'References to deprecated APIs', value: pluginStats.deprecatedAPIsReferencedCount, }, diff --git a/packages/kbn-es/src/cluster.js b/packages/kbn-es/src/cluster.js index 0866b14f4ade8..dd9c17055fb18 100644 --- a/packages/kbn-es/src/cluster.js +++ b/packages/kbn-es/src/cluster.js @@ -36,7 +36,7 @@ const first = (stream, map) => exports.Cluster = class Cluster { constructor({ log = defaultLog, ssl = false } = {}) { - this._log = log; + this._log = log.withType('@kbn/es Cluster'); this._ssl = ssl; this._caCertPromise = ssl ? readFile(CA_CERT_PATH) : undefined; } diff --git a/packages/kbn-es/src/integration_tests/cluster.test.js b/packages/kbn-es/src/integration_tests/cluster.test.js index c196a89a6b090..0cdbac310bbb1 100644 --- a/packages/kbn-es/src/integration_tests/cluster.test.js +++ b/packages/kbn-es/src/integration_tests/cluster.test.js @@ -8,9 +8,11 @@ const { ToolingLog, + ToolingLogCollectingWriter, ES_P12_PATH, ES_P12_PASSWORD, createAnyInstanceSerializer, + createStripAnsiSerializer, } = require('@kbn/dev-utils'); const execa = require('execa'); const { Cluster } = require('../cluster'); @@ -18,6 +20,7 @@ const { installSource, installSnapshot, installArchive } = require('../install') const { extractConfigFiles } = require('../utils/extract_config_files'); expect.addSnapshotSerializer(createAnyInstanceSerializer(ToolingLog)); +expect.addSnapshotSerializer(createStripAnsiSerializer()); jest.mock('../install', () => ({ installSource: jest.fn(), @@ -31,6 +34,8 @@ jest.mock('../utils/extract_config_files', () => ({ })); const log = new ToolingLog(); +const logWriter = new ToolingLogCollectingWriter(); +log.setWriters([logWriter]); function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -76,6 +81,8 @@ const initialEnv = { ...process.env }; beforeEach(() => { jest.resetAllMocks(); extractConfigFiles.mockImplementation((config) => config); + log.indent(-log.getIndent()); + logWriter.messages.length = 0; }); afterEach(() => { @@ -107,11 +114,21 @@ describe('#installSource()', () => { installSource.mockResolvedValue({}); const cluster = new Cluster({ log }); await cluster.installSource({ foo: 'bar' }); - expect(installSource).toHaveBeenCalledTimes(1); - expect(installSource).toHaveBeenCalledWith({ - log, - foo: 'bar', - }); + expect(installSource.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "foo": "bar", + "log": <ToolingLog>, + }, + ], + ] + `); + expect(logWriter.messages).toMatchInlineSnapshot(` + Array [ + " info source[@kbn/es Cluster] Installing from source", + ] + `); }); it('rejects if installSource() rejects', async () => { @@ -146,11 +163,21 @@ describe('#installSnapshot()', () => { installSnapshot.mockResolvedValue({}); const cluster = new Cluster({ log }); await cluster.installSnapshot({ foo: 'bar' }); - expect(installSnapshot).toHaveBeenCalledTimes(1); - expect(installSnapshot).toHaveBeenCalledWith({ - log, - foo: 'bar', - }); + expect(installSnapshot.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "foo": "bar", + "log": <ToolingLog>, + }, + ], + ] + `); + expect(logWriter.messages).toMatchInlineSnapshot(` + Array [ + " info source[@kbn/es Cluster] Installing from snapshot", + ] + `); }); it('rejects if installSnapshot() rejects', async () => { @@ -185,11 +212,22 @@ describe('#installArchive(path)', () => { installArchive.mockResolvedValue({}); const cluster = new Cluster({ log }); await cluster.installArchive('path', { foo: 'bar' }); - expect(installArchive).toHaveBeenCalledTimes(1); - expect(installArchive).toHaveBeenCalledWith('path', { - log, - foo: 'bar', - }); + expect(installArchive.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + "path", + Object { + "foo": "bar", + "log": <ToolingLog>, + }, + ], + ] + `); + expect(logWriter.messages).toMatchInlineSnapshot(` + Array [ + " info source[@kbn/es Cluster] Installing from an archive", + ] + `); }); it('rejects if installArchive() rejects', async () => { diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index acef661d93bb0..f331bb6dae444 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -2,8 +2,6 @@ pageLoadAssetSize: advancedSettings: 27596 alerting: 106936 apm: 64385 - apmOss: 18996 - bfetch: 51874 canvas: 1066647 charts: 95000 cloud: 21076 @@ -12,17 +10,12 @@ pageLoadAssetSize: crossClusterReplication: 65408 dashboard: 374194 dashboardEnhanced: 65646 - data: 824229 - dataEnhanced: 50420 devTools: 38637 discover: 99999 discoverEnhanced: 42730 - embeddable: 99999 - embeddableEnhanced: 41145 enterpriseSearch: 35741 esUiShared: 326654 features: 21723 - fieldFormats: 92628 globalSearch: 29696 globalSearchBar: 50403 globalSearchProviders: 25554 @@ -31,8 +24,6 @@ pageLoadAssetSize: home: 30182 indexLifecycleManagement: 107090 indexManagement: 140608 - indexPatternManagement: 28222 - indexPatternEditor: 25000 infra: 184320 fleet: 250000 ingestPipelines: 58003 @@ -40,8 +31,6 @@ pageLoadAssetSize: inspector: 148711 kibanaLegacy: 107711 kibanaOverview: 56279 - kibanaReact: 188705 - kibanaUtils: 198829 lens: 96624 licenseManagement: 41817 licensing: 29004 @@ -56,7 +45,6 @@ pageLoadAssetSize: observability: 89709 painlessLab: 179748 remoteClusters: 51327 - reporting: 183418 rollup: 97204 savedObjects: 108518 savedObjectsManagement: 101836 @@ -64,18 +52,14 @@ pageLoadAssetSize: savedObjectsTaggingOss: 20590 searchprofiler: 67080 security: 95864 - share: 99061 snapshotRestore: 79032 spaces: 57868 telemetry: 51957 telemetryManagementSection: 38586 transform: 41007 triggersActionsUi: 100000 - uiActions: 97717 - uiActionsEnhanced: 32000 upgradeAssistant: 81241 uptime: 40825 - urlDrilldown: 70674 urlForwarding: 32579 usageCollection: 39762 visDefaultEditor: 50178 @@ -93,7 +77,6 @@ pageLoadAssetSize: runtimeFields: 41752 stackAlerts: 29684 presentationUtil: 94301 - indexPatternFieldEditor: 50000 osquery: 107090 fileUpload: 25664 dataVisualizer: 27530 @@ -111,9 +94,25 @@ pageLoadAssetSize: expressionShape: 34008 interactiveSetup: 80000 expressionTagcloud: 27505 - expressions: 239290 securitySolution: 231753 customIntegrations: 28810 expressionMetricVis: 23121 visTypeMetric: 23332 - dataViews: 42000 + bfetch: 22837 + kibanaUtils: 97808 + data: 491273 + dataViews: 41532 + expressions: 140958 + fieldFormats: 65209 + kibanaReact: 99422 + share: 71239 + uiActions: 35121 + dataEnhanced: 24980 + embeddable: 87309 + embeddableEnhanced: 22107 + uiActionsEnhanced: 38494 + urlDrilldown: 30063 + indexPatternEditor: 19123 + indexPatternFieldEditor: 34448 + indexPatternManagement: 19165 + reporting: 57003 diff --git a/packages/kbn-optimizer/src/cli.ts b/packages/kbn-optimizer/src/cli.ts index 7f0c39ccd0e55..41ca656259fc6 100644 --- a/packages/kbn-optimizer/src/cli.ts +++ b/packages/kbn-optimizer/src/cli.ts @@ -207,7 +207,7 @@ export function runKbnOptimizerCli(options: { defaultLimitsPath: string }) { --no-inspect-workers when inspecting the parent process, don't inspect the workers --limits path to a limits.yml file to read, defaults to $KBN_OPTIMIZER_LIMITS_PATH or source file --validate-limits validate the limits.yml config to ensure that there are limits defined for every bundle - --update-limits run a build and rewrite the limits file to include the current bundle sizes +5kb + --update-limits run a build and rewrite the limits file to include the current bundle sizes +15kb `, }, } diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 3c0e3fa94be02..721072d9e899b 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -625,12 +625,20 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && * Side Public License, v 1. */ class ToolingLog { - constructor(writerConfig) { - (0, _defineProperty2.default)(this, "indentWidth", 0); - (0, _defineProperty2.default)(this, "writers", void 0); + constructor(writerConfig, options) { + (0, _defineProperty2.default)(this, "indentWidth$", void 0); + (0, _defineProperty2.default)(this, "writers$", void 0); (0, _defineProperty2.default)(this, "written$", void 0); - this.writers = writerConfig ? [new _tooling_log_text_writer.ToolingLogTextWriter(writerConfig)] : []; - this.written$ = new Rx.Subject(); + (0, _defineProperty2.default)(this, "type", void 0); + this.indentWidth$ = options !== null && options !== void 0 && options.parent ? options.parent.indentWidth$ : new Rx.BehaviorSubject(0); + this.writers$ = options !== null && options !== void 0 && options.parent ? options.parent.writers$ : new Rx.BehaviorSubject([]); + + if (!(options !== null && options !== void 0 && options.parent) && writerConfig) { + this.writers$.next([new _tooling_log_text_writer.ToolingLogTextWriter(writerConfig)]); + } + + this.written$ = options !== null && options !== void 0 && options.parent ? options.parent.written$ : new Rx.Subject(); + this.type = options === null || options === void 0 ? void 0 : options.type; } /** * Get the current indentation level of the ToolingLog @@ -638,7 +646,7 @@ class ToolingLog { getIndent() { - return this.indentWidth; + return this.indentWidth$.getValue(); } /** * Indent the output of the ToolingLog by some character (4 is a good choice usually). @@ -652,8 +660,8 @@ class ToolingLog { indent(delta = 0, block) { - const originalWidth = this.indentWidth; - this.indentWidth = Math.max(this.indentWidth + delta, 0); + const originalWidth = this.indentWidth$.getValue(); + this.indentWidth$.next(Math.max(originalWidth + delta, 0)); if (!block) { return; @@ -663,7 +671,7 @@ class ToolingLog { try { return await block(); } finally { - this.indentWidth = originalWidth; + this.indentWidth$.next(originalWidth); } })(); } @@ -697,26 +705,41 @@ class ToolingLog { } getWriters() { - return this.writers.slice(0); + return [...this.writers$.getValue()]; } setWriters(writers) { - this.writers = [...writers]; + this.writers$.next([...writers]); } getWritten$() { return this.written$.asObservable(); } + /** + * Create a new ToolingLog which sets a different "type", allowing messages to be filtered out by "source" + * @param type A string that will be passed along with messages from this logger which can be used to filter messages with `ignoreSources` + */ + + + withType(type) { + return new ToolingLog(undefined, { + type, + parent: this + }); + } sendToWriters(type, args) { + const indent = this.indentWidth$.getValue(); + const writers = this.writers$.getValue(); const msg = { type, - indent: this.indentWidth, + indent, + source: this.type, args }; let written = false; - for (const writer of this.writers) { + for (const writer of writers) { if (writer.write(msg)) { written = true; } @@ -6618,8 +6641,10 @@ class ToolingLogTextWriter { constructor(config) { (0, _defineProperty2.default)(this, "level", void 0); (0, _defineProperty2.default)(this, "writeTo", void 0); + (0, _defineProperty2.default)(this, "ignoreSources", void 0); this.level = (0, _log_levels.parseLogLevel)(config.level); this.writeTo = config.writeTo; + this.ignoreSources = config.ignoreSources; if (!this.writeTo || typeof this.writeTo.write !== 'function') { throw new Error('ToolingLogTextWriter requires the `writeTo` option be set to a stream (like process.stdout)'); @@ -6631,6 +6656,10 @@ class ToolingLogTextWriter { return false; } + if (this.ignoreSources && msg.source && this.ignoreSources.includes(msg.source)) { + return false; + } + const prefix = has(MSG_PREFIXES, msg.type) ? MSG_PREFIXES[msg.type] : ''; ToolingLogTextWriter.write(this.writeTo, prefix, msg); return true; @@ -8773,6 +8802,20 @@ class ToolingLogCollectingWriter extends _tooling_log_text_writer.ToolingLogText }); (0, _defineProperty2.default)(this, "messages", []); } + /** + * Called by ToolingLog, extends messages with the source if message includes one. + */ + + + write(msg) { + if (msg.source) { + return super.write({ ...msg, + args: [`source[${msg.source}]`, ...msg.args] + }); + } + + return super.write(msg); + } } @@ -9075,7 +9118,7 @@ class CiStatsReporter { try { const { stdout - } = await (0, _execa.default)('git', ['branch', '--show-current']); + } = await (0, _execa.default)('git', ['rev-parse', '--abbrev-ref', 'HEAD']); branch = stdout; } catch (e) { this.log.debug(e.message); @@ -15466,6 +15509,12 @@ exports.parseConfig = parseConfig; * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + +/** + * Information about how CiStatsReporter should talk to the ci-stats service. Normally + * it is read from a JSON environment variable using the `parseConfig()` function + * exported by this module. + */ function validateConfig(log, config) { const validApiToken = typeof config.apiToken === 'string' && config.apiToken.length !== 0; diff --git a/packages/kbn-securitysolution-list-api/src/api/index.ts b/packages/kbn-securitysolution-list-api/src/api/index.ts index d70417a29971f..77c50fb32c299 100644 --- a/packages/kbn-securitysolution-list-api/src/api/index.ts +++ b/packages/kbn-securitysolution-list-api/src/api/index.ts @@ -558,7 +558,7 @@ export const exportExceptionList = async ({ signal, }: ExportExceptionListProps): Promise<Blob> => http.fetch<Blob>(`${EXCEPTION_LIST_URL}/_export`, { - method: 'GET', + method: 'POST', query: { id, list_id: listId, namespace_type: namespaceType }, signal, }); diff --git a/packages/kbn-securitysolution-utils/src/index.ts b/packages/kbn-securitysolution-utils/src/index.ts index 0bb36c590ffdf..755bbd2203dff 100644 --- a/packages/kbn-securitysolution-utils/src/index.ts +++ b/packages/kbn-securitysolution-utils/src/index.ts @@ -7,3 +7,4 @@ */ export * from './add_remove_id_to_item'; +export * from './transform_data_to_ndjson'; diff --git a/packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.test.ts b/packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.test.ts new file mode 100644 index 0000000000000..b10626357f5b1 --- /dev/null +++ b/packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.test.ts @@ -0,0 +1,88 @@ +/* + * Copyright 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 { transformDataToNdjson } from './'; + +export const ANCHOR_DATE = '2020-02-20T03:57:54.037Z'; + +const getRulesSchemaMock = (anchorDate: string = ANCHOR_DATE) => ({ + author: [], + id: '7a7065d7-6e8b-4aae-8d20-c93613dec9f9', + created_at: new Date(anchorDate).toISOString(), + updated_at: new Date(anchorDate).toISOString(), + created_by: 'elastic', + description: 'some description', + enabled: true, + false_positives: ['false positive 1', 'false positive 2'], + from: 'now-6m', + immutable: false, + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + references: ['test 1', 'test 2'], + severity: 'high', + severity_mapping: [], + updated_by: 'elastic_kibana', + tags: ['some fake tag 1', 'some fake tag 2'], + to: 'now', + type: 'query', + threat: [], + version: 1, + status: 'succeeded', + status_date: '2020-02-22T16:47:50.047Z', + last_success_at: '2020-02-22T16:47:50.047Z', + last_success_message: 'succeeded', + output_index: '.siem-signals-default', + max_signals: 100, + risk_score: 55, + risk_score_mapping: [], + language: 'kuery', + rule_id: 'query-rule-id', + interval: '5m', + exceptions_list: [], +}); + +describe('transformDataToNdjson', () => { + test('if rules are empty it returns an empty string', () => { + const ruleNdjson = transformDataToNdjson([]); + expect(ruleNdjson).toEqual(''); + }); + + test('single rule will transform with new line ending character for ndjson', () => { + const rule = getRulesSchemaMock(); + const ruleNdjson = transformDataToNdjson([rule]); + expect(ruleNdjson.endsWith('\n')).toBe(true); + }); + + test('multiple rules will transform with two new line ending characters for ndjson', () => { + const result1 = getRulesSchemaMock(); + const result2 = getRulesSchemaMock(); + result2.id = 'some other id'; + result2.rule_id = 'some other id'; + result2.name = 'Some other rule'; + + const ruleNdjson = transformDataToNdjson([result1, result2]); + // this is how we count characters in JavaScript :-) + const count = ruleNdjson.split('\n').length - 1; + expect(count).toBe(2); + }); + + test('you can parse two rules back out without errors', () => { + const result1 = getRulesSchemaMock(); + const result2 = getRulesSchemaMock(); + result2.id = 'some other id'; + result2.rule_id = 'some other id'; + result2.name = 'Some other rule'; + + const ruleNdjson = transformDataToNdjson([result1, result2]); + const ruleStrings = ruleNdjson.split('\n'); + const reParsed1 = JSON.parse(ruleStrings[0]); + const reParsed2 = JSON.parse(ruleStrings[1]); + expect(reParsed1).toEqual(result1); + expect(reParsed2).toEqual(result2); + }); +}); diff --git a/src/plugins/apm_oss/public/index.ts b/packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.ts similarity index 56% rename from src/plugins/apm_oss/public/index.ts rename to packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.ts index fea8ac4a8a1e4..66a500731f497 100644 --- a/src/plugins/apm_oss/public/index.ts +++ b/packages/kbn-securitysolution-utils/src/transform_data_to_ndjson/index.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { ApmOssPlugin } from './plugin'; - -// This exports static code and TypeScript types, -// as well as, Kibana Platform `plugin()` initializer. -export function plugin() { - return new ApmOssPlugin(); -} -export { ApmOssPluginSetup, ApmOssPluginStart } from './types'; +export const transformDataToNdjson = (data: unknown[]): string => { + if (data.length !== 0) { + const dataString = data.map((item) => JSON.stringify(item)).join('\n'); + return `${dataString}\n`; + } else { + return ''; + } +}; diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js index 43229ff2d1c98..d6045b71bf3a7 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js @@ -62,6 +62,7 @@ export function MochaReporterProvider({ getService }) { log.setWriters([ new ToolingLogTextWriter({ level: 'error', + ignoreSources: ['ProcRunner', '@kbn/es Cluster'], writeTo: process.stdout, }), new ToolingLogTextWriter({ @@ -136,7 +137,7 @@ export function MochaReporterProvider({ getService }) { onPass = (test) => { const time = colors.speed(test.speed, ` (${ms(test.duration)})`); const pass = colors.pass(`${symbols.ok} pass`); - log.write(`- ${pass} ${time} "${test.fullTitle()}"`); + log.write(`- ${pass} ${time}`); }; onFail = (runnable) => { diff --git a/packages/kbn-test/src/functional_tests/tasks.ts b/packages/kbn-test/src/functional_tests/tasks.ts index c8265c032cbcc..b220c3899a638 100644 --- a/packages/kbn-test/src/functional_tests/tasks.ts +++ b/packages/kbn-test/src/functional_tests/tasks.ts @@ -90,7 +90,7 @@ export async function runTests(options: RunTestsParams) { log.write('--- determining which ftr configs to run'); const configPathsWithTests: string[] = []; for (const configPath of options.configs) { - log.info('testing', configPath); + log.info('testing', relative(REPO_ROOT, configPath)); await log.indent(4, async () => { if (await hasTests({ configPath, options: { ...options, log } })) { configPathsWithTests.push(configPath); @@ -98,9 +98,10 @@ export async function runTests(options: RunTestsParams) { }); } - for (const configPath of configPathsWithTests) { + for (const [i, configPath] of configPathsWithTests.entries()) { await log.indent(0, async () => { - log.write(`--- Running ${relative(REPO_ROOT, configPath)}`); + const progress = `${i + 1}/${configPathsWithTests.length}`; + log.write(`--- [${progress}] Running ${relative(REPO_ROOT, configPath)}`); await withProcRunner(log, async (procs) => { const config = await readConfigFile(log, configPath); diff --git a/packages/kbn-ui-shared-deps-npm/BUILD.bazel b/packages/kbn-ui-shared-deps-npm/BUILD.bazel index ae3a6f05d456b..2ca08a34d761f 100644 --- a/packages/kbn-ui-shared-deps-npm/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-npm/BUILD.bazel @@ -30,7 +30,6 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "//packages/elastic-datemath", - "//packages/kbn-utils", "@npm//@babel/runtime", "@npm//@elastic/charts", "@npm//@elastic/eui", @@ -61,6 +60,7 @@ RUNTIME_DEPS = [ "@npm//rxjs", "@npm//styled-components", "@npm//symbol-observable", + "@npm//tslib", "@npm//url-loader", "@npm//val-loader", "@npm//whatwg-fetch", @@ -71,8 +71,6 @@ WEBPACK_DEPS = [ ] TYPES_DEPS = [ - "//packages/elastic-datemath", - "//packages/kbn-utils", "@npm//@elastic/charts", "@npm//@elastic/eui", "@npm//@elastic/numeral", diff --git a/packages/kbn-ui-shared-deps-npm/webpack.config.js b/packages/kbn-ui-shared-deps-npm/webpack.config.js index 6c37e2e9adf9e..c06ce6704f451 100644 --- a/packages/kbn-ui-shared-deps-npm/webpack.config.js +++ b/packages/kbn-ui-shared-deps-npm/webpack.config.js @@ -11,13 +11,13 @@ const webpack = require('webpack'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const { REPO_ROOT } = require('@kbn/utils'); - const UiSharedDepsNpm = require('./src/index'); const MOMENT_SRC = require.resolve('moment/min/moment-with-locales.js'); const WEBPACK_SRC = require.resolve('webpack'); +const REPO_ROOT = Path.resolve(__dirname, '..', '..'); + module.exports = (_, argv) => { const outputPath = argv.outputPath ? Path.resolve(argv.outputPath) : UiSharedDepsNpm.distDir; @@ -40,7 +40,6 @@ module.exports = (_, argv) => { // modules from npm '@elastic/charts', - '@elastic/datemath', '@elastic/eui', '@elastic/eui/dist/eui_charts_theme', '@elastic/eui/lib/services', diff --git a/packages/kbn-ui-shared-deps-src/.babelrc b/packages/kbn-ui-shared-deps-src/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-ui-shared-deps-src/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-ui-shared-deps-src/BUILD.bazel b/packages/kbn-ui-shared-deps-src/BUILD.bazel index f23c86769fb49..d1c9115c0515b 100644 --- a/packages/kbn-ui-shared-deps-src/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-src/BUILD.bazel @@ -38,7 +38,6 @@ RUNTIME_DEPS = [ "//packages/kbn-monaco", "//packages/kbn-std", "//packages/kbn-ui-shared-deps-npm", - "//packages/kbn-utils", ] TYPES_DEPS = [ @@ -50,9 +49,7 @@ TYPES_DEPS = [ "//packages/kbn-monaco", "//packages/kbn-std", "//packages/kbn-ui-shared-deps-npm", - "//packages/kbn-utils", "@npm//@elastic/eui", - "@npm//resize-observer-polyfill", "@npm//webpack", ] diff --git a/packages/kbn-ui-shared-deps-src/webpack.config.js b/packages/kbn-ui-shared-deps-src/webpack.config.js index 125a3539dd667..ad84c9444fd0f 100644 --- a/packages/kbn-ui-shared-deps-src/webpack.config.js +++ b/packages/kbn-ui-shared-deps-src/webpack.config.js @@ -10,13 +10,14 @@ const Path = require('path'); const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const { REPO_ROOT } = require('@kbn/utils'); const UiSharedDepsNpm = require('@kbn/ui-shared-deps-npm'); const UiSharedDepsSrc = require('./src'); const MOMENT_SRC = require.resolve('moment/min/moment-with-locales.js'); +const REPO_ROOT = Path.resolve(__dirname, '..', '..'); + module.exports = { node: { child_process: 'empty', diff --git a/renovate.json5 b/renovate.json5 index b08d7e0bcec1e..76923f01daba0 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -93,6 +93,15 @@ labels: ['Feature:Vega', 'Team:VisEditors'], enabled: true, }, + { + groupName: 'cypress', + packageNames: ['eslint-plugin-cypress'], + matchPackagePatterns: ["^cypress"], + reviewers: ['Team:apm', 'Team: SecuritySolution'], + matchBaseBranches: ['master'], + labels: ['buildkite-ci', 'ci:all-cypress-suites'], + enabled: true, + } { groupName: 'platform security modules', packageNames: [ diff --git a/src/core/public/core_app/status/components/__snapshots__/status_table.test.tsx.snap b/src/core/public/core_app/status/components/__snapshots__/status_table.test.tsx.snap index 16b67bfa0584f..5b0e831286aad 100644 --- a/src/core/public/core_app/status/components/__snapshots__/status_table.test.tsx.snap +++ b/src/core/public/core_app/status/components/__snapshots__/status_table.test.tsx.snap @@ -35,7 +35,12 @@ exports[`StatusTable renders when statuses is provided 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} rowProps={[Function]} tableLayout="fixed" diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 01108298adc99..ac0aac3466f5f 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -26,12 +26,14 @@ export class DocLinksService { const PLUGIN_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/plugins/${DOC_LINK_VERSION}/`; const APM_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/apm/`; const SECURITY_SOLUTION_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/`; + const STACK_GETTING_STARTED = `${ELASTIC_WEBSITE_URL}guide/en/elastic-stack-get-started/${DOC_LINK_VERSION}/`; return deepFreeze({ DOC_LINK_VERSION, ELASTIC_WEBSITE_URL, links: { settings: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/settings.html`, + elasticStackGetStarted: `${STACK_GETTING_STARTED}get-started-elastic-stack.html`, apm: { kibanaSettings: `${KIBANA_DOCS}apm-settings-in-kibana.html`, supportedServiceMaps: `${KIBANA_DOCS}service-maps.html#service-maps-supported`, @@ -233,6 +235,9 @@ export class DocLinksService { networkMap: `${SECURITY_SOLUTION_DOCS}conf-map-ui.html`, troubleshootGaps: `${SECURITY_SOLUTION_DOCS}alerts-ui-monitor.html#troubleshoot-gaps`, }, + securitySolution: { + trustedApps: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/trusted-apps-ov.html`, + }, query: { eql: `${ELASTICSEARCH_DOCS}eql.html`, kueryQuerySyntax: `${KIBANA_DOCS}kuery-query.html`, @@ -477,6 +482,7 @@ export class DocLinksService { upgradeElasticAgent: `${FLEET_DOCS}upgrade-elastic-agent.html`, upgradeElasticAgent712lower: `${FLEET_DOCS}upgrade-elastic-agent.html#upgrade-7.12-lower`, learnMoreBlog: `${ELASTIC_WEBSITE_URL}blog/elastic-agent-and-fleet-make-it-easier-to-integrate-your-systems-with-elastic`, + apiKeysLearnMore: `${KIBANA_DOCS}api-keys.html`, }, ecs: { guide: `${ELASTIC_WEBSITE_URL}guide/en/ecs/current/index.html`, @@ -505,6 +511,7 @@ export interface DocLinksStart { readonly ELASTIC_WEBSITE_URL: string; readonly links: { readonly settings: string; + readonly elasticStackGetStarted: string; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; @@ -641,6 +648,9 @@ export interface DocLinksStart { readonly networkMap: string; readonly troubleshootGaps: string; }; + readonly securitySolution: { + readonly trustedApps: string; + }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; @@ -732,6 +742,7 @@ export interface DocLinksStart { upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; + apiKeysLearnMore: string; }>; readonly ecs: { readonly guide: string; diff --git a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap index 54e223cdc5d41..d714f2159d1a2 100644 --- a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap +++ b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap @@ -7,6 +7,7 @@ exports[`#start() returns \`Context\` component 1`] = ` Object { "mapping": Object { "euiAccordion.isLoading": "Loading", + "euiBasicTable.noItemsMessage": "No items found", "euiBasicTable.selectAllRows": "Select all rows", "euiBasicTable.selectThisRow": "Select this row", "euiBasicTable.tableAutoCaptionWithPagination": [Function], @@ -120,13 +121,15 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiLink.external.ariaLabel": "External link", "euiLink.newTarget.screenReaderOnlyText": "(opens in a new tab or window)", "euiMarkdownEditorFooter.closeButton": "Close", - "euiMarkdownEditorFooter.descriptionPrefix": "This editor uses", - "euiMarkdownEditorFooter.descriptionSuffix": "You can also utilize these additional syntax plugins to add rich content to your text.", "euiMarkdownEditorFooter.errorsTitle": "Errors", + "euiMarkdownEditorFooter.mdSyntaxLink": "GitHub flavored markdown", "euiMarkdownEditorFooter.openUploadModal": "Open upload files modal", "euiMarkdownEditorFooter.showMarkdownHelp": "Show markdown help", "euiMarkdownEditorFooter.showSyntaxErrors": "Show errors", "euiMarkdownEditorFooter.supportedFileTypes": [Function], + "euiMarkdownEditorFooter.syntaxModalDescriptionPrefix": "This editor uses", + "euiMarkdownEditorFooter.syntaxModalDescriptionSuffix": "You can also utilize these additional syntax plugins to add rich content to your text.", + "euiMarkdownEditorFooter.syntaxPopoverDescription": "This editor uses", "euiMarkdownEditorFooter.syntaxTitle": "Syntax help", "euiMarkdownEditorFooter.unsupportedFileType": "File type not supported", "euiMarkdownEditorFooter.uploadingFiles": "Click to upload files", diff --git a/src/core/public/i18n/i18n_eui_mapping.tsx b/src/core/public/i18n/i18n_eui_mapping.tsx index 2fe9657bce8c9..7585ada886c05 100644 --- a/src/core/public/i18n/i18n_eui_mapping.tsx +++ b/src/core/public/i18n/i18n_eui_mapping.tsx @@ -68,6 +68,9 @@ export const getEuiContextMapping = (): EuiTokensObject => { values: { tableCaption }, description: 'Screen reader text to describe the pagination controls', }), + 'euiBasicTable.noItemsMessage': i18n.translate('core.euiBasicTable.noItemsMessage', { + defaultMessage: 'No items found', + }), 'euiBottomBar.customScreenReaderAnnouncement': ({ landmarkHeading }: EuiValues) => i18n.translate('core.euiBottomBar.customScreenReaderAnnouncement', { defaultMessage: @@ -634,19 +637,31 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'Syntax help', } ), - 'euiMarkdownEditorFooter.descriptionPrefix': i18n.translate( - 'core.euiMarkdownEditorFooter.descriptionPrefix', + 'euiMarkdownEditorFooter.mdSyntaxLink': i18n.translate( + 'core.euiMarkdownEditorFooter.mdSyntaxLink', + { + defaultMessage: 'GitHub flavored markdown', + } + ), + 'euiMarkdownEditorFooter.syntaxModalDescriptionPrefix': i18n.translate( + 'core.euiMarkdownEditorFooter.syntaxModalDescriptionPrefix', { defaultMessage: 'This editor uses', } ), - 'euiMarkdownEditorFooter.descriptionSuffix': i18n.translate( - 'core.euiMarkdownEditorFooter.descriptionSuffix', + 'euiMarkdownEditorFooter.syntaxModalDescriptionSuffix': i18n.translate( + 'core.euiMarkdownEditorFooter.syntaxModalDescriptionSuffix', { defaultMessage: 'You can also utilize these additional syntax plugins to add rich content to your text.', } ), + 'euiMarkdownEditorFooter.syntaxPopoverDescription': i18n.translate( + 'core.euiMarkdownEditorFooter.syntaxPopoverDescription', + { + defaultMessage: 'This editor uses', + } + ), 'euiMarkdownEditorToolbar.editor': i18n.translate('core.euiMarkdownEditorToolbar.editor', { defaultMessage: 'Editor', }), diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 45b7e3bdc02b5..50c9bcf925969 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -478,6 +478,7 @@ export interface DocLinksStart { // (undocumented) readonly links: { readonly settings: string; + readonly elasticStackGetStarted: string; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; @@ -614,6 +615,9 @@ export interface DocLinksStart { readonly networkMap: string; readonly troubleshootGaps: string; }; + readonly securitySolution: { + readonly trustedApps: string; + }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; @@ -705,6 +709,7 @@ export interface DocLinksStart { upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; + apiKeysLearnMore: string; }>; readonly ecs: { readonly guide: string; diff --git a/src/core/public/rendering/_base.scss b/src/core/public/rendering/_base.scss index 18e564abf822f..32a297a4066d9 100644 --- a/src/core/public/rendering/_base.scss +++ b/src/core/public/rendering/_base.scss @@ -42,6 +42,12 @@ #app-fixed-viewport { top: $headerHeight; } + + .kbnStickyMenu { + position: sticky; + max-height: calc(100vh - #{$headerHeight + $euiSize}); + top: $headerHeight + $euiSize; + } } .kbnBody { diff --git a/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts index 21e99d83443f6..0a5864dcefac2 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts @@ -55,7 +55,8 @@ const { startES } = kbnTestServer.createTestServers({ }); let esServer: kbnTestServer.TestElasticsearchUtils; -describe('migration actions', () => { +// Failing: See https://github.com/elastic/kibana/issues/113697 +describe.skip('migration actions', () => { let client: ElasticsearchClient; beforeAll(async () => { diff --git a/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts b/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts index 5f0665692b46f..02b469820f900 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts @@ -8,8 +8,9 @@ import { resolve } from 'path'; import { readFileSync } from 'fs'; +import { copyFile } from 'fs/promises'; -import { ToolingLog } from '@kbn/dev-utils'; +import { ToolingLog, REPO_ROOT } from '@kbn/dev-utils'; import Mustache from 'mustache'; import { compressTar, copyAll, mkdirp, write, Config } from '../../../lib'; @@ -39,9 +40,10 @@ export async function bundleDockerFiles(config: Config, log: ToolingLog, scope: await copyAll(resolve(scope.dockerBuildDir, 'bin'), resolve(dockerFilesBuildDir, 'bin')); await copyAll(resolve(scope.dockerBuildDir, 'config'), resolve(dockerFilesBuildDir, 'config')); if (scope.ironbank) { - await copyAll(resolve(scope.dockerBuildDir), resolve(dockerFilesBuildDir), { - select: ['LICENSE'], - }); + await copyFile( + resolve(REPO_ROOT, 'licenses/ELASTIC-LICENSE-2.0.txt'), + resolve(dockerFilesBuildDir, 'LICENSE') + ); const templates = ['hardening_manifest.yaml', 'README.md']; for (const template of templates) { const file = readFileSync(resolve(__dirname, 'templates/ironbank', template)); 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 2f3c610d905e7..4a8f9df4c4044 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 @@ -211,6 +211,12 @@ kibana_vars=( xpack.alerts.invalidateApiKeysTask.interval xpack.alerts.invalidateApiKeysTask.removalDelay xpack.apm.enabled + xpack.apm.indices.error + xpack.apm.indices.metric + xpack.apm.indices.onboarding + xpack.apm.indices.sourcemap + xpack.apm.indices.span + xpack.apm.indices.transaction xpack.apm.maxServiceEnvironments xpack.apm.searchAggregatedTransactions xpack.apm.serviceMapEnabled diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/ironbank/LICENSE b/src/dev/build/tasks/os_packages/docker_generator/resources/ironbank/LICENSE deleted file mode 100644 index 632c3abe22e9b..0000000000000 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/ironbank/LICENSE +++ /dev/null @@ -1,280 +0,0 @@ -ELASTIC LICENSE AGREEMENT - -PLEASE READ CAREFULLY THIS ELASTIC LICENSE AGREEMENT (THIS "AGREEMENT"), WHICH -CONSTITUTES A LEGALLY BINDING AGREEMENT AND GOVERNS ALL OF YOUR USE OF ALL OF -THE ELASTIC SOFTWARE WITH WHICH THIS AGREEMENT IS INCLUDED ("ELASTIC SOFTWARE") -THAT IS PROVIDED IN OBJECT CODE FORMAT, AND, IN ACCORDANCE WITH SECTION 2 BELOW, -CERTAIN OF THE ELASTIC SOFTWARE THAT IS PROVIDED IN SOURCE CODE FORMAT. BY -INSTALLING OR USING ANY OF THE ELASTIC SOFTWARE GOVERNED BY THIS AGREEMENT, YOU -ARE ASSENTING TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE -WITH SUCH TERMS AND CONDITIONS, YOU MAY NOT INSTALL OR USE THE ELASTIC SOFTWARE -GOVERNED BY THIS AGREEMENT. IF YOU ARE INSTALLING OR USING THE SOFTWARE ON -BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU HAVE THE ACTUAL -AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT ON BEHALF OF -SUCH ENTITY. - -Posted Date: April 20, 2018 - -This Agreement is entered into by and between Elasticsearch BV ("Elastic") and -You, or the legal entity on behalf of whom You are acting (as applicable, -"You"). - -1. OBJECT CODE END USER LICENSES, RESTRICTIONS AND THIRD PARTY OPEN SOURCE -SOFTWARE - - 1.1 Object Code End User License. Subject to the terms and conditions of - Section 1.2 of this Agreement, Elastic hereby grants to You, AT NO CHARGE and - for so long as you are not in breach of any provision of this Agreement, a - License to the Basic Features and Functions of the Elastic Software. - - 1.2 Reservation of Rights; Restrictions. As between Elastic and You, Elastic - and its licensors own all right, title and interest in and to the Elastic - Software, and except as expressly set forth in Sections 1.1, and 2.1 of this - Agreement, no other license to the Elastic Software is granted to You under - this Agreement, by implication, estoppel or otherwise. You agree not to: (i) - reverse engineer or decompile, decrypt, disassemble or otherwise reduce any - Elastic Software provided to You in Object Code, or any portion thereof, to - Source Code, except and only to the extent any such restriction is prohibited - by applicable law, (ii) except as expressly permitted in this Agreement, - prepare derivative works from, modify, copy or use the Elastic Software Object - Code or the Commercial Software Source Code in any manner; (iii) except as - expressly permitted in Section 1.1 above, transfer, sell, rent, lease, - distribute, sublicense, loan or otherwise transfer, Elastic Software Object - Code, in whole or in part, to any third party; (iv) use Elastic Software - Object Code for providing time-sharing services, any software-as-a-service, - service bureau services or as part of an application services provider or - other service offering (collectively, "SaaS Offering") where obtaining access - to the Elastic Software or the features and functions of the Elastic Software - is a primary reason or substantial motivation for users of the SaaS Offering - to access and/or use the SaaS Offering ("Prohibited SaaS Offering"); (v) - circumvent the limitations on use of Elastic Software provided to You in - Object Code format that are imposed or preserved by any License Key, or (vi) - alter or remove any Marks and Notices in the Elastic Software. If You have any - question as to whether a specific SaaS Offering constitutes a Prohibited SaaS - Offering, or are interested in obtaining Elastic's permission to engage in - commercial or non-commercial distribution of the Elastic Software, please - contact elastic_license@elastic.co. - - 1.3 Third Party Open Source Software. The Commercial Software may contain or - be provided with third party open source libraries, components, utilities and - other open source software (collectively, "Open Source Software"), which Open - Source Software may have applicable license terms as identified on a website - designated by Elastic. Notwithstanding anything to the contrary herein, use of - the Open Source Software shall be subject to the license terms and conditions - applicable to such Open Source Software, to the extent required by the - applicable licensor (which terms shall not restrict the license rights granted - to You hereunder, but may contain additional rights). To the extent any - condition of this Agreement conflicts with any license to the Open Source - Software, the Open Source Software license will govern with respect to such - Open Source Software only. Elastic may also separately provide you with - certain open source software that is licensed by Elastic. Your use of such - Elastic open source software will not be governed by this Agreement, but by - the applicable open source license terms. - -2. COMMERCIAL SOFTWARE SOURCE CODE - - 2.1 Limited License. Subject to the terms and conditions of Section 2.2 of - this Agreement, Elastic hereby grants to You, AT NO CHARGE and for so long as - you are not in breach of any provision of this Agreement, a limited, - non-exclusive, non-transferable, fully paid up royalty free right and license - to the Commercial Software in Source Code format, without the right to grant - or authorize sublicenses, to prepare Derivative Works of the Commercial - Software, provided You (i) do not hack the licensing mechanism, or otherwise - circumvent the intended limitations on the use of Elastic Software to enable - features other than Basic Features and Functions or those features You are - entitled to as part of a Subscription, and (ii) use the resulting object code - only for reasonable testing purposes. - - 2.2 Restrictions. Nothing in Section 2.1 grants You the right to (i) use the - Commercial Software Source Code other than in accordance with Section 2.1 - above, (ii) use a Derivative Work of the Commercial Software outside of a - Non-production Environment, in any production capacity, on a temporary or - permanent basis, or (iii) transfer, sell, rent, lease, distribute, sublicense, - loan or otherwise make available the Commercial Software Source Code, in whole - or in part, to any third party. Notwithstanding the foregoing, You may - maintain a copy of the repository in which the Source Code of the Commercial - Software resides and that copy may be publicly accessible, provided that you - include this Agreement with Your copy of the repository. - -3. TERMINATION - - 3.1 Termination. This Agreement will automatically terminate, whether or not - You receive notice of such Termination from Elastic, if You breach any of its - provisions. - - 3.2 Post Termination. Upon any termination of this Agreement, for any reason, - You shall promptly cease the use of the Elastic Software in Object Code format - and cease use of the Commercial Software in Source Code format. For the - avoidance of doubt, termination of this Agreement will not affect Your right - to use Elastic Software, in either Object Code or Source Code formats, made - available under the Apache License Version 2.0. - - 3.3 Survival. Sections 1.2, 2.2. 3.3, 4 and 5 shall survive any termination or - expiration of this Agreement. - -4. DISCLAIMER OF WARRANTIES AND LIMITATION OF LIABILITY - - 4.1 Disclaimer of Warranties. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE - LAW, THE ELASTIC SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, - AND ELASTIC AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR - STATUTORY REGARDING OR RELATING TO THE ELASTIC SOFTWARE. TO THE MAXIMUM EXTENT - PERMITTED UNDER APPLICABLE LAW, ELASTIC AND ITS LICENSORS SPECIFICALLY - DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE AND NON-INFRINGEMENT WITH RESPECT TO THE ELASTIC SOFTWARE, AND WITH - RESPECT TO THE USE OF THE FOREGOING. FURTHER, ELASTIC DOES NOT WARRANT RESULTS - OF USE OR THAT THE ELASTIC SOFTWARE WILL BE ERROR FREE OR THAT THE USE OF THE - ELASTIC SOFTWARE WILL BE UNINTERRUPTED. - - 4.2 Limitation of Liability. IN NO EVENT SHALL ELASTIC OR ITS LICENSORS BE - LIABLE TO YOU OR ANY THIRD PARTY FOR ANY DIRECT OR INDIRECT DAMAGES, - INCLUDING, WITHOUT LIMITATION, FOR ANY LOSS OF PROFITS, LOSS OF USE, BUSINESS - INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, IN CONNECTION WITH - OR ARISING OUT OF THE USE OR INABILITY TO USE THE ELASTIC SOFTWARE, OR THE - PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A - BREACH OF CONTRACT OR TORTIOUS CONDUCT, INCLUDING NEGLIGENCE, EVEN IF ELASTIC - HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -5. MISCELLANEOUS - - This Agreement completely and exclusively states the entire agreement of the - parties regarding the subject matter herein, and it supersedes, and its terms - govern, all prior proposals, agreements, or other communications between the - parties, oral or written, regarding such subject matter. This Agreement may be - modified by Elastic from time to time, and any such modifications will be - effective upon the "Posted Date" set forth at the top of the modified - Agreement. If any provision hereof is held unenforceable, this Agreement will - continue without said provision and be interpreted to reflect the original - intent of the parties. This Agreement and any non-contractual obligation - arising out of or in connection with it, is governed exclusively by Dutch law. - This Agreement shall not be governed by the 1980 UN Convention on Contracts - for the International Sale of Goods. All disputes arising out of or in - connection with this Agreement, including its existence and validity, shall be - resolved by the courts with jurisdiction in Amsterdam, The Netherlands, except - where mandatory law provides for the courts at another location in The - Netherlands to have jurisdiction. The parties hereby irrevocably waive any and - all claims and defenses either might otherwise have in any such action or - proceeding in any of such courts based upon any alleged lack of personal - jurisdiction, improper venue, forum non conveniens or any similar claim or - defense. A breach or threatened breach, by You of Section 2 may cause - irreparable harm for which damages at law may not provide adequate relief, and - therefore Elastic shall be entitled to seek injunctive relief without being - required to post a bond. You may not assign this Agreement (including by - operation of law in connection with a merger or acquisition), in whole or in - part to any third party without the prior written consent of Elastic, which - may be withheld or granted by Elastic in its sole and absolute discretion. - Any assignment in violation of the preceding sentence is void. Notices to - Elastic may also be sent to legal@elastic.co. - -6. DEFINITIONS - - The following terms have the meanings ascribed: - - 6.1 "Affiliate" means, with respect to a party, any entity that controls, is - controlled by, or which is under common control with, such party, where - "control" means ownership of at least fifty percent (50%) of the outstanding - voting shares of the entity, or the contractual right to establish policy for, - and manage the operations of, the entity. - - 6.2 "Basic Features and Functions" means those features and functions of the - Elastic Software that are eligible for use under a Basic license, as set forth - at https://www.elastic.co/subscriptions, as may be modified by Elastic from - time to time. - - 6.3 "Commercial Software" means the Elastic Software Source Code in any file - containing a header stating the contents are subject to the Elastic License or - which is contained in the repository folder labeled "x-pack", unless a LICENSE - file present in the directory subtree declares a different license. - - 6.4 "Derivative Work of the Commercial Software" means, for purposes of this - Agreement, any modification(s) or enhancement(s) to the Commercial Software, - which represent, as a whole, an original work of authorship. - - 6.5 "License" means a limited, non-exclusive, non-transferable, fully paid up, - royalty free, right and license, without the right to grant or authorize - sublicenses, solely for Your internal business operations to (i) install and - use the applicable Features and Functions of the Elastic Software in Object - Code, and (ii) permit Contractors and Your Affiliates to use the Elastic - software as set forth in (i) above, provided that such use by Contractors must - be solely for Your benefit and/or the benefit of Your Affiliates, and You - shall be responsible for all acts and omissions of such Contractors and - Affiliates in connection with their use of the Elastic software that are - contrary to the terms and conditions of this Agreement. - - 6.6 "License Key" means a sequence of bytes, including but not limited to a - JSON blob, that is used to enable certain features and functions of the - Elastic Software. - - 6.7 "Marks and Notices" means all Elastic trademarks, trade names, logos and - notices present on the Documentation as originally provided by Elastic. - - 6.8 "Non-production Environment" means an environment for development, testing - or quality assurance, where software is not used for production purposes. - - 6.9 "Object Code" means any form resulting from mechanical transformation or - translation of Source Code form, including but not limited to compiled object - code, generated documentation, and conversions to other media types. - - 6.10 "Source Code" means the preferred form of computer software for making - modifications, including but not limited to software source code, - documentation source, and configuration files. - - 6.11 "Subscription" means the right to receive Support Services and a License - to the Commercial Software. - - -GOVERNMENT END USER ADDENDUM TO THE ELASTIC LICENSE AGREEMENT - - This ADDENDUM TO THE ELASTIC LICENSE AGREEMENT (this "Addendum") applies -only to U.S. Federal Government, State Government, and Local Government -entities ("Government End Users") of the Elastic Software. This Addendum is -subject to, and hereby incorporated into, the Elastic License Agreement, -which is being entered into as of even date herewith, by Elastic and You (the -"Agreement"). This Addendum sets forth additional terms and conditions -related to Your use of the Elastic Software. Capitalized terms not defined in -this Addendum have the meaning set forth in the Agreement. - - 1. LIMITED LICENSE TO DISTRIBUTE (DSOP ONLY). Subject to the terms and -conditions of the Agreement (including this Addendum), Elastic grants the -Department of Defense Enterprise DevSecOps Initiative (DSOP) a royalty-free, -non-exclusive, non-transferable, limited license to reproduce and distribute -the Elastic Software solely through a software distribution repository -controlled and managed by DSOP, provided that DSOP: (i) distributes the -Elastic Software complete and unmodified, inclusive of the Agreement -(including this Addendum) and (ii) does not remove or alter any proprietary -legends or notices contained in the Elastic Software. - - 2. CHOICE OF LAW. The choice of law and venue provisions set forth shall -prevail over those set forth in Section 5 of the Agreement. - - "For U.S. Federal Government Entity End Users. This Agreement and any - non-contractual obligation arising out of or in connection with it, is - governed exclusively by U.S. Federal law. To the extent permitted by - federal law, the laws of the State of Delaware (excluding Delaware choice - of law rules) will apply in the absence of applicable federal law. - - For State and Local Government Entity End Users. This Agreement and any - non-contractual obligation arising out of or in connection with it, is - governed exclusively by the laws of the state in which you are located - without reference to conflict of laws. Furthermore, the Parties agree that - the Uniform Computer Information Transactions Act or any version thereof, - adopted by any state in any form ('UCITA'), shall not apply to this - Agreement and, to the extent that UCITA is applicable, the Parties agree to - opt out of the applicability of UCITA pursuant to the opt-out provision(s) - contained therein." - - 3. ELASTIC LICENSE MODIFICATION. Section 5 of the Agreement is hereby -amended to replace - - "This Agreement may be modified by Elastic from time to time, and any - such modifications will be effective upon the "Posted Date" set forth at - the top of the modified Agreement." - - with: - - "This Agreement may be modified by Elastic from time to time; provided, - however, that any such modifications shall apply only to Elastic Software - that is installed after the "Posted Date" set forth at the top of the - modified Agreement." - -V100820.0 diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/README.md b/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/README.md index d297d135149f4..d81b219900a85 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/README.md +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/README.md @@ -31,9 +31,9 @@ You can learn more about the Elastic Community and also understand how to get mo visiting [Elastic Community](https://www.elastic.co/community). This software is governed by the [Elastic -License](https://github.com/elastic/elasticsearch/blob/{{branch}}/licenses/ELASTIC-LICENSE.txt), +License](https://github.com/elastic/kibana/blob/{{branch}}/licenses/ELASTIC-LICENSE-2.0.txt), and includes the full set of [free features](https://www.elastic.co/subscriptions). View the detailed release notes -[here](https://www.elastic.co/guide/en/elasticsearch/reference/{{branch}}/es-release-notes.html). +[here](https://www.elastic.co/guide/en/kibana/{{branch}}/release-notes-{{version}}.html). diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/hardening_manifest.yaml b/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/hardening_manifest.yaml index 2e65e68bc2882..24614039e5eb7 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/hardening_manifest.yaml +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/hardening_manifest.yaml @@ -56,3 +56,7 @@ maintainers: name: 'Alexander Klepal' username: 'alexander.klepal' cht_member: true + - email: "yalabe.dukuly@anchore.com" + name: "Yalabe Dukuly" + username: "yalabe.dukuly" + cht_member: true \ No newline at end of file diff --git a/src/dev/ci_setup/.bazelrc-ci b/src/dev/ci_setup/.bazelrc-ci index ef6fab3a30590..9aee657f37bcb 100644 --- a/src/dev/ci_setup/.bazelrc-ci +++ b/src/dev/ci_setup/.bazelrc-ci @@ -1,16 +1,15 @@ -# Inspired on https://github.com/angular/angular/blob/master/.circleci/bazel.linux.rc -# These options are only enabled when running on CI -# That is done by copying this file into "$HOME/.bazelrc" which loads after the .bazelrc into the workspace +# Used in the on-merge job to persist the Bazel cache to BuildBuddy +# from: .buildkite/scripts/common/persist_bazel_cache.sh -# Import and load bazelrc common settings for ci env -try-import %workspace%/src/dev/ci_setup/.bazelrc-ci.common +import %workspace%/.bazelrc.common # BuildBuddy settings -## Remote settings including cache build --bes_results_url=https://app.buildbuddy.io/invocation/ build --bes_backend=grpcs://cloud.buildbuddy.io build --remote_cache=grpcs://cloud.buildbuddy.io build --remote_timeout=3600 +# --remote_header=x-buildbuddy-api-key= # appended in CI script -## Metadata settings +# Metadata settings build --build_metadata=ROLE=CI +build --workspace_status_command="node ./src/dev/bazel_workspace_status.js" diff --git a/src/dev/ci_setup/.bazelrc-ci.common b/src/dev/ci_setup/.bazelrc-ci.common deleted file mode 100644 index 56a5ee8d30cd6..0000000000000 --- a/src/dev/ci_setup/.bazelrc-ci.common +++ /dev/null @@ -1,11 +0,0 @@ -# Inspired on https://github.com/angular/angular/blob/master/.circleci/bazel.common.rc -# Settings in this file should be OS agnostic - -# Don't be spammy in the logs -build --noshow_progress - -# More details on failures -build --verbose_failures=true - -## Avoid to keep connections to build event backend connections alive across builds -build --keep_backend_build_event_connections_alive=false diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index e4f1c6a2d2e01..a4ae39848735e 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -74,7 +74,7 @@ export const DEV_ONLY_LICENSE_ALLOWED = ['MPL-2.0']; export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint - '@elastic/ems-client@7.15.0': ['Elastic License 2.0'], - '@elastic/eui@38.0.1': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/ems-client@7.16.0': ['Elastic License 2.0'], + '@elastic/eui@39.0.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry }; diff --git a/src/dev/typescript/run_type_check_cli.ts b/src/dev/typescript/run_type_check_cli.ts index 472b9c04757ca..27998f881a03d 100644 --- a/src/dev/typescript/run_type_check_cli.ts +++ b/src/dev/typescript/run_type_check_cli.ts @@ -53,23 +53,8 @@ export async function runTypeCheckCli() { } } - const nonCompositeProjects = projects.filter((p) => !p.isCompositeProject()); - if (!nonCompositeProjects.length) { - if (projectFilter) { - log.success( - `${flags.project} is a composite project so its types are validated by scripts/build_ts_refs` - ); - } else { - log.success( - `All projects are composite so their types are validated by scripts/build_ts_refs` - ); - } - - return; - } - const concurrency = Math.min(4, Math.round((Os.cpus() || []).length / 2) || 1) || 1; - log.info('running type check in', nonCompositeProjects.length, 'non-composite projects'); + log.info('running type check in', projects.length, 'projects'); const tscArgs = [ ...['--emitDeclarationOnly', 'false'], @@ -81,7 +66,7 @@ export async function runTypeCheckCli() { ]; const failureCount = await lastValueFrom( - Rx.from(nonCompositeProjects).pipe( + Rx.from(projects).pipe( mergeMap(async (p) => { const relativePath = Path.relative(process.cwd(), p.tsConfigPath); diff --git a/src/plugins/apm_oss/README.asciidoc b/src/plugins/apm_oss/README.asciidoc deleted file mode 100644 index c3c060a99ee27..0000000000000 --- a/src/plugins/apm_oss/README.asciidoc +++ /dev/null @@ -1,5 +0,0 @@ -# APM OSS plugin - -OSS plugin for APM. Includes index configuration and tutorial resources. - -See <<../../x-pack/plugins/apm/readme.md,the X-Pack APM plugin README>> for information about the main APM plugin. diff --git a/src/plugins/apm_oss/kibana.json b/src/plugins/apm_oss/kibana.json deleted file mode 100644 index f18b275add9e3..0000000000000 --- a/src/plugins/apm_oss/kibana.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "apmOss", - "owner": { - "name": "APM UI", - "githubTeam": "apm-ui" - }, - "version": "8.0.0", - "server": true, - "kibanaVersion": "kibana", - "configPath": ["apm_oss"], - "ui": true, - "requiredPlugins": ["home"] -} diff --git a/src/plugins/apm_oss/public/plugin.ts b/src/plugins/apm_oss/public/plugin.ts deleted file mode 100644 index e6981954b301a..0000000000000 --- a/src/plugins/apm_oss/public/plugin.ts +++ /dev/null @@ -1,22 +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 { CoreSetup, CoreStart, Plugin } from 'kibana/public'; -import { ApmOssPluginSetup, ApmOssPluginStart } from './types'; - -export class ApmOssPlugin implements Plugin<ApmOssPluginSetup, ApmOssPluginStart> { - public setup(core: CoreSetup): ApmOssPluginSetup { - return {}; - } - - public start(core: CoreStart): ApmOssPluginStart { - return {}; - } - - public stop() {} -} diff --git a/src/plugins/apm_oss/server/index.ts b/src/plugins/apm_oss/server/index.ts deleted file mode 100644 index f2f6777672e33..0000000000000 --- a/src/plugins/apm_oss/server/index.ts +++ /dev/null @@ -1,40 +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 { schema, TypeOf } from '@kbn/config-schema'; -import { ConfigDeprecationProvider, PluginInitializerContext } from '../../../core/server'; -import { APMOSSPlugin } from './plugin'; - -const deprecations: ConfigDeprecationProvider = ({ deprecate, unused }) => [ - deprecate('enabled', '8.0.0'), - unused('fleetMode'), - unused('indexPattern'), -]; - -export const config = { - schema: schema.object({ - enabled: schema.boolean({ defaultValue: true }), - transactionIndices: schema.string({ defaultValue: 'apm-*' }), - spanIndices: schema.string({ defaultValue: 'apm-*' }), - errorIndices: schema.string({ defaultValue: 'apm-*' }), - metricsIndices: schema.string({ defaultValue: 'apm-*' }), - sourcemapIndices: schema.string({ defaultValue: 'apm-*' }), - onboardingIndices: schema.string({ defaultValue: 'apm-*' }), - indexPattern: schema.string({ defaultValue: 'apm-*' }), - fleetMode: schema.boolean({ defaultValue: true }), - }), - deprecations, -}; - -export function plugin(initializerContext: PluginInitializerContext) { - return new APMOSSPlugin(initializerContext); -} - -export type APMOSSConfig = TypeOf<typeof config.schema>; - -export { APMOSSPluginSetup } from './plugin'; diff --git a/src/plugins/apm_oss/server/plugin.ts b/src/plugins/apm_oss/server/plugin.ts deleted file mode 100644 index 02a8ac38be2a3..0000000000000 --- a/src/plugins/apm_oss/server/plugin.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 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 { Observable } from 'rxjs'; -import { Plugin, PluginInitializerContext } from 'src/core/server'; -import { APMOSSConfig } from './'; - -export class APMOSSPlugin implements Plugin<APMOSSPluginSetup> { - constructor(private readonly initContext: PluginInitializerContext) { - this.initContext = initContext; - } - public setup() { - const config$ = this.initContext.config.create<APMOSSConfig>(); - const config = this.initContext.config.get<APMOSSConfig>(); - return { config, config$ }; - } - - start() {} - stop() {} -} - -export interface APMOSSPluginSetup { - config: APMOSSConfig; - config$: Observable<APMOSSConfig>; -} diff --git a/src/plugins/apm_oss/tsconfig.json b/src/plugins/apm_oss/tsconfig.json deleted file mode 100644 index 08ed86d5da0a8..0000000000000 --- a/src/plugins/apm_oss/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true - }, - "include": [ - "common/**/*", - "public/**/*", - "server/**/*", - // have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636 - "server/tutorial/index_pattern.json" - ], - "references": [{ "path": "../../core/tsconfig.json" }, { "path": "../home/tsconfig.json" }] -} diff --git a/src/plugins/custom_integrations/common/index.ts b/src/plugins/custom_integrations/common/index.ts index 9af7c4ccd4633..de2a6592465a2 100755 --- a/src/plugins/custom_integrations/common/index.ts +++ b/src/plugins/custom_integrations/common/index.ts @@ -42,9 +42,6 @@ export const INTEGRATION_CATEGORY_DISPLAY = { // Kibana added upload_file: 'Upload a file', language_client: 'Language client', - - // Internal - updates_available: 'Updates available', }; /** diff --git a/src/plugins/custom_integrations/public/services/stub/fixtures/integrations.ts b/src/plugins/custom_integrations/public/services/stub/fixtures/integrations.ts index 7553deada9e26..5e4427a66cc76 100644 --- a/src/plugins/custom_integrations/public/services/stub/fixtures/integrations.ts +++ b/src/plugins/custom_integrations/public/services/stub/fixtures/integrations.ts @@ -10,1875 +10,54 @@ import type { CustomIntegration } from '../../../../common'; export const integrations: CustomIntegration[] = [ { - type: 'ui_link', - id: 'System logs', - title: 'System logs', - categories: ['os_system', 'security'], - uiInternalPath: '/app/home#/tutorial/systemLogs', - description: 'Collect system logs of common Unix/Linux based distributions.', - icons: [ - { - type: 'eui', - src: 'logoLogging', - }, - ], - shipper: 'beats', - eprOverlap: 'system', - isBeta: false, - }, - { - type: 'ui_link', - id: 'System metrics', - title: 'System metrics', - categories: ['os_system', 'security'], - uiInternalPath: '/app/home#/tutorial/systemMetrics', - description: 'Collect CPU, memory, network, and disk statistics from the host.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/system.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'system', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Apache logs', - title: 'Apache logs', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/apacheLogs', - description: 'Collect and parse access and error logs created by the Apache HTTP server.', - icons: [ - { - type: 'eui', - src: 'logoApache', - }, - ], - shipper: 'beats', - eprOverlap: 'apache', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Apache metrics', - title: 'Apache metrics', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/apacheMetrics', - description: 'Fetch internal metrics from the Apache 2 HTTP server.', - icons: [ - { - type: 'eui', - src: 'logoApache', - }, - ], - shipper: 'beats', - eprOverlap: 'apache', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Elasticsearch logs', - title: 'Elasticsearch logs', - categories: ['containers', 'os_system'], - uiInternalPath: '/app/home#/tutorial/elasticsearchLogs', - description: 'Collect and parse logs created by Elasticsearch.', - icons: [ - { - type: 'eui', - src: 'logoElasticsearch', - }, - ], - shipper: 'beats', - eprOverlap: 'elasticsearch', - isBeta: false, - }, - { - type: 'ui_link', - id: 'IIS logs', - title: 'IIS logs', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/iisLogs', - description: 'Collect and parse access and error logs created by the IIS HTTP server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/iis.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'iis', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Kafka logs', - title: 'Kafka logs', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/kafkaLogs', - description: 'Collect and parse logs created by Kafka.', - icons: [ - { - type: 'eui', - src: 'logoKafka', - }, - ], - shipper: 'beats', - eprOverlap: 'kafka', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Logstash logs', - title: 'Logstash logs', - categories: ['custom'], - uiInternalPath: '/app/home#/tutorial/logstashLogs', - description: 'Collect Logstash main and slow logs.', - icons: [ - { - type: 'eui', - src: 'logoLogstash', - }, - ], - shipper: 'beats', - eprOverlap: 'logstash', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Nginx logs', - title: 'Nginx logs', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/nginxLogs', - description: 'Collect and parse access and error logs created by the Nginx HTTP server.', - icons: [ - { - type: 'eui', - src: 'logoNginx', - }, - ], - shipper: 'beats', - eprOverlap: 'nginx', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Nginx metrics', - title: 'Nginx metrics', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/nginxMetrics', - description: 'Fetch internal metrics from the Nginx HTTP server.', - icons: [ - { - type: 'eui', - src: 'logoNginx', - }, - ], - shipper: 'beats', - eprOverlap: 'nginx', - isBeta: false, - }, - { - type: 'ui_link', - id: 'MySQL logs', - title: 'MySQL logs', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/mysqlLogs', - description: 'Collect and parse error and slow logs created by MySQL.', - icons: [ - { - type: 'eui', - src: 'logoMySQL', - }, - ], - shipper: 'beats', - eprOverlap: 'mysql', - isBeta: false, - }, - { - type: 'ui_link', - id: 'MySQL metrics', - title: 'MySQL metrics', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/mysqlMetrics', - description: 'Fetch internal metrics from MySQL.', - icons: [ - { - type: 'eui', - src: 'logoMySQL', - }, - ], - shipper: 'beats', - eprOverlap: 'mysql', - isBeta: false, - }, - { - type: 'ui_link', - id: 'MongoDB metrics', - title: 'MongoDB metrics', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/mongodbMetrics', - description: 'Fetch internal metrics from MongoDB.', - icons: [ - { - type: 'eui', - src: 'logoMongodb', - }, - ], - shipper: 'beats', - eprOverlap: 'mongodb', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Osquery logs', - title: 'Osquery logs', - categories: ['security', 'os_system'], - uiInternalPath: '/app/home#/tutorial/osqueryLogs', - description: 'Collect osquery logs in JSON format.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/osquery.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'osquery', + id: 'b.ga_beats', + categories: ['azure', 'cloud', 'config_management'], + description: 'Beats for a GA package that is not installed', isBeta: false, - }, - { - type: 'ui_link', - id: 'PHP-FPM metrics', - title: 'PHP-FPM metrics', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/phpfpmMetrics', - description: 'Fetch internal metrics from PHP-FPM.', - icons: [ - { - type: 'eui', - src: 'logoPhp', - }, - ], shipper: 'beats', - eprOverlap: 'php_fpm', - isBeta: false, - }, - { - type: 'ui_link', - id: 'PostgreSQL metrics', - title: 'PostgreSQL metrics', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/postgresqlMetrics', - description: 'Fetch internal metrics from PostgreSQL.', icons: [ { type: 'eui', - src: 'logoPostgres', + src: 'logoBeats', }, ], - shipper: 'beats', - eprOverlap: 'postgresql', - isBeta: false, - }, - { + title: 'b. GA, has Beats', type: 'ui_link', - id: 'PostgreSQL logs', - title: 'PostgreSQL logs', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/postgresqlLogs', - description: 'Collect and parse error and slow logs created by PostgreSQL.', - icons: [ - { - type: 'eui', - src: 'logoPostgres', - }, - ], - shipper: 'beats', - eprOverlap: 'postgresql', - isBeta: false, + uiInternalPath: '/', + eprOverlap: 'ga_beats', }, { - type: 'ui_link', - id: 'RabbitMQ metrics', - title: 'RabbitMQ metrics', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/rabbitmqMetrics', - description: 'Fetch internal metrics from the RabbitMQ server.', - icons: [ - { - type: 'eui', - src: 'logoRabbitmq', - }, - ], - shipper: 'beats', - eprOverlap: 'rabbitmq', + id: 'f.beta_beats', + categories: ['azure', 'cloud', 'config_management'], + description: 'Beats for a beta package that is not installed', isBeta: false, - }, - { - type: 'ui_link', - id: 'Redis logs', - title: 'Redis logs', - categories: ['datastore', 'message_queue'], - uiInternalPath: '/app/home#/tutorial/redisLogs', - description: 'Collect and parse error and slow logs created by Redis.', - icons: [ - { - type: 'eui', - src: 'logoRedis', - }, - ], shipper: 'beats', - eprOverlap: 'redis', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Redis metrics', - title: 'Redis metrics', - categories: ['datastore', 'message_queue'], - uiInternalPath: '/app/home#/tutorial/redisMetrics', - description: 'Fetch internal metrics from Redis.', icons: [ { type: 'eui', - src: 'logoRedis', - }, - ], - shipper: 'beats', - eprOverlap: 'redis', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Suricata logs', - title: 'Suricata logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/suricataLogs', - description: 'Collect Suricata IDS/IPS/NSM logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/suricata.svg', + src: 'logoBeats', }, ], - shipper: 'beats', - eprOverlap: 'suricata', - isBeta: false, - }, - { + title: 'f. Beta, has Beats', type: 'ui_link', - id: 'Docker metrics', - title: 'Docker metrics', - categories: ['containers', 'os_system'], - uiInternalPath: '/app/home#/tutorial/dockerMetrics', - description: 'Fetch metrics about your Docker containers.', - icons: [ - { - type: 'eui', - src: 'logoDocker', - }, - ], - shipper: 'beats', - eprOverlap: 'docker', - isBeta: false, + uiInternalPath: '/', + eprOverlap: 'beta_beats', }, { - type: 'ui_link', - id: 'Kubernetes metrics', - title: 'Kubernetes metrics', - categories: ['containers', 'kubernetes'], - uiInternalPath: '/app/home#/tutorial/kubernetesMetrics', - description: 'Fetch metrics from your Kubernetes installation.', - icons: [ - { - type: 'eui', - src: 'logoKubernetes', - }, - ], - shipper: 'beats', - eprOverlap: 'kubernetes', + id: 'j.exp_beats', + categories: ['azure', 'cloud', 'config_management'], + description: 'Beats for an experimental package that is not installed', isBeta: false, - }, - { - type: 'ui_link', - id: 'uWSGI metrics', - title: 'uWSGI metrics', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/uwsgiMetrics', - description: 'Fetch internal metrics from the uWSGI server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/uwsgi.svg', - }, - ], shipper: 'beats', - eprOverlap: 'uwsgi', - isBeta: false, - }, - { - type: 'ui_link', - id: 'NetFlow / IPFIX Collector', - title: 'NetFlow / IPFIX Collector', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/netflowLogs', - description: 'Collect NetFlow and IPFIX flow records.', icons: [ { type: 'eui', src: 'logoBeats', }, ], - shipper: 'beats', - eprOverlap: 'netflow', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Traefik logs', - title: 'Traefik logs', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/traefikLogs', - description: 'Collect Traefik access logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/traefik.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'traefik', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Ceph metrics', - title: 'Ceph metrics', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/cephMetrics', - description: 'Fetch internal metrics from the Ceph server.', - icons: [ - { - type: 'eui', - src: 'logoCeph', - }, - ], - shipper: 'beats', - eprOverlap: 'ceph', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Aerospike metrics', - title: 'Aerospike metrics', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/aerospikeMetrics', - description: 'Fetch internal metrics from the Aerospike server.', - icons: [ - { - type: 'eui', - src: 'logoAerospike', - }, - ], - shipper: 'beats', - eprOverlap: 'aerospike', - isBeta: false, - }, - { + title: 'j. Experimental, has Beats', type: 'ui_link', - id: 'Couchbase metrics', - title: 'Couchbase metrics', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/couchbaseMetrics', - description: 'Fetch internal metrics from Couchbase.', - icons: [ - { - type: 'eui', - src: 'logoCouchbase', - }, - ], - shipper: 'beats', - eprOverlap: 'couchbase', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Dropwizard metrics', - title: 'Dropwizard metrics', - categories: ['elastic_stack', 'datastore'], - uiInternalPath: '/app/home#/tutorial/dropwizardMetrics', - description: 'Fetch internal metrics from Dropwizard Java application.', - icons: [ - { - type: 'eui', - src: 'logoDropwizard', - }, - ], - shipper: 'beats', - eprOverlap: 'dropwizard', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Elasticsearch metrics', - title: 'Elasticsearch metrics', - categories: ['elastic_stack', 'datastore'], - uiInternalPath: '/app/home#/tutorial/elasticsearchMetrics', - description: 'Fetch internal metrics from Elasticsearch.', - icons: [ - { - type: 'eui', - src: 'logoElasticsearch', - }, - ], - shipper: 'beats', - eprOverlap: 'elasticsearch', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Etcd metrics', - title: 'Etcd metrics', - categories: ['elastic_stack', 'datastore'], - uiInternalPath: '/app/home#/tutorial/etcdMetrics', - description: 'Fetch internal metrics from the Etcd server.', - icons: [ - { - type: 'eui', - src: 'logoEtcd', - }, - ], - shipper: 'beats', - eprOverlap: 'etcd', - isBeta: false, - }, - { - type: 'ui_link', - id: 'HAProxy metrics', - title: 'HAProxy metrics', - categories: ['network', 'web'], - uiInternalPath: '/app/home#/tutorial/haproxyMetrics', - description: 'Fetch internal metrics from the HAProxy server.', - icons: [ - { - type: 'eui', - src: 'logoHAproxy', - }, - ], - shipper: 'beats', - eprOverlap: 'haproxy', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Kafka metrics', - title: 'Kafka metrics', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/kafkaMetrics', - description: 'Fetch internal metrics from the Kafka server.', - icons: [ - { - type: 'eui', - src: 'logoKafka', - }, - ], - shipper: 'beats', - eprOverlap: 'kafka', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Kibana metrics', - title: 'Kibana metrics', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/kibanaMetrics', - description: 'Fetch internal metrics from Kibana.', - icons: [ - { - type: 'eui', - src: 'logoKibana', - }, - ], - shipper: 'beats', - eprOverlap: 'kibana', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Memcached metrics', - title: 'Memcached metrics', - categories: ['custom'], - uiInternalPath: '/app/home#/tutorial/memcachedMetrics', - description: 'Fetch internal metrics from the Memcached server.', - icons: [ - { - type: 'eui', - src: 'logoMemcached', - }, - ], - shipper: 'beats', - eprOverlap: 'memcached', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Munin metrics', - title: 'Munin metrics', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/muninMetrics', - description: 'Fetch internal metrics from the Munin server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/munin.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'munin', - isBeta: false, - }, - { - type: 'ui_link', - id: 'vSphere metrics', - title: 'vSphere metrics', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/vsphereMetrics', - description: 'Fetch internal metrics from vSphere.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/vsphere.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'vsphere', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Windows metrics', - title: 'Windows metrics', - categories: ['os_system', 'security'], - uiInternalPath: '/app/home#/tutorial/windowsMetrics', - description: 'Fetch internal metrics from Windows.', - icons: [ - { - type: 'eui', - src: 'logoWindows', - }, - ], - shipper: 'beats', - eprOverlap: 'windows', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Windows Event Log', - title: 'Windows Event Log', - categories: ['os_system', 'security'], - uiInternalPath: '/app/home#/tutorial/windowsEventLogs', - description: 'Fetch logs from the Windows Event Log.', - icons: [ - { - type: 'eui', - src: 'logoWindows', - }, - ], - shipper: 'beats', - eprOverlap: 'windows', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Golang metrics', - title: 'Golang metrics', - categories: ['google_cloud', 'cloud', 'network', 'security'], - uiInternalPath: '/app/home#/tutorial/golangMetrics', - description: 'Fetch internal metrics from a Golang app.', - icons: [ - { - type: 'eui', - src: 'logoGolang', - }, - ], - shipper: 'beats', - eprOverlap: 'golang', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Logstash metrics', - title: 'Logstash metrics', - categories: ['custom'], - uiInternalPath: '/app/home#/tutorial/logstashMetrics', - description: 'Fetch internal metrics from a Logstash server.', - icons: [ - { - type: 'eui', - src: 'logoLogstash', - }, - ], - shipper: 'beats', - eprOverlap: 'logstash', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Prometheus metrics', - title: 'Prometheus metrics', - categories: ['monitoring', 'datastore'], - uiInternalPath: '/app/home#/tutorial/prometheusMetrics', - description: 'Fetch metrics from a Prometheus exporter.', - icons: [ - { - type: 'eui', - src: 'logoPrometheus', - }, - ], - shipper: 'beats', - eprOverlap: 'prometheus', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Zookeeper metrics', - title: 'Zookeeper metrics', - categories: ['datastore', 'config_management'], - uiInternalPath: '/app/home#/tutorial/zookeeperMetrics', - description: 'Fetch internal metrics from a Zookeeper server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/zookeeper.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'zookeeper', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Uptime Monitors', - title: 'Uptime Monitors', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/uptimeMonitors', - description: 'Monitor services for their availability', - icons: [ - { - type: 'eui', - src: 'uptimeApp', - }, - ], - shipper: 'beats', - eprOverlap: 'uptime', - isBeta: false, - }, - { - type: 'ui_link', - id: 'AWS Cloudwatch logs', - title: 'AWS Cloudwatch logs', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/cloudwatchLogs', - description: 'Collect Cloudwatch logs with Functionbeat.', - icons: [ - { - type: 'eui', - src: 'logoAWS', - }, - ], - shipper: 'beats', - eprOverlap: 'aws', - isBeta: false, - }, - { - type: 'ui_link', - id: 'AWS metrics', - title: 'AWS metrics', - categories: ['aws', 'cloud', 'datastore', 'security', 'network'], - uiInternalPath: '/app/home#/tutorial/awsMetrics', - description: 'Fetch monitoring metrics for EC2 instances from the AWS APIs and Cloudwatch.', - icons: [ - { - type: 'eui', - src: 'logoAWS', - }, - ], - shipper: 'beats', - eprOverlap: 'aws', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Microsoft SQL Server Metrics', - title: 'Microsoft SQL Server Metrics', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/mssqlMetrics', - description: 'Fetch monitoring metrics from a Microsoft SQL Server instance', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/mssql.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'mssql', - isBeta: false, - }, - { - type: 'ui_link', - id: 'NATS metrics', - title: 'NATS metrics', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/natsMetrics', - description: 'Fetch monitoring metrics from the Nats server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/nats.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'nats', - isBeta: false, - }, - { - type: 'ui_link', - id: 'NATS logs', - title: 'NATS logs', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/natsLogs', - description: 'Collect and parse logs created by Nats.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/nats.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'nats', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Zeek logs', - title: 'Zeek logs', - categories: ['network', 'monitoring', 'security'], - uiInternalPath: '/app/home#/tutorial/zeekLogs', - description: 'Collect Zeek network security monitoring logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/zeek.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'zeek', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CoreDNS metrics', - title: 'CoreDNS metrics', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/corednsMetrics', - description: 'Fetch monitoring metrics from the CoreDNS server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/coredns.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'coredns', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CoreDNS logs', - title: 'CoreDNS logs', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/corednsLogs', - description: 'Collect CoreDNS logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/coredns.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'coredns', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Auditbeat', - title: 'Auditbeat', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/auditbeat', - description: 'Collect audit data from your hosts.', - icons: [ - { - type: 'eui', - src: 'securityAnalyticsApp', - }, - ], - shipper: 'beats', - eprOverlap: 'auditbeat', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Iptables logs', - title: 'Iptables logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/iptablesLogs', - description: 'Collect iptables and ip6tables logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/linux.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'iptables', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Cisco logs', - title: 'Cisco logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/ciscoLogs', - description: 'Collect Cisco network device logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/cisco.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'cisco', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Envoy Proxy logs', - title: 'Envoy Proxy logs', - categories: ['elastic_stack', 'datastore'], - uiInternalPath: '/app/home#/tutorial/envoyproxyLogs', - description: 'Collect Envoy Proxy logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/envoyproxy.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'envoyproxy', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CouchDB metrics', - title: 'CouchDB metrics', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/couchdbMetrics', - description: 'Fetch monitoring metrics from the CouchdB server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/couchdb.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'couchdb', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Consul metrics', - title: 'Consul metrics', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/consulMetrics', - description: 'Fetch monitoring metrics from the Consul server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/consul.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'consul', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CockroachDB metrics', - title: 'CockroachDB metrics', - categories: ['security', 'network', 'web'], - uiInternalPath: '/app/home#/tutorial/cockroachdbMetrics', - description: 'Fetch monitoring metrics from the CockroachDB server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/cockroachdb.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'cockroachdb', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Traefik metrics', - title: 'Traefik metrics', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/traefikMetrics', - description: 'Fetch monitoring metrics from Traefik.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/traefik.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'traefik', - isBeta: false, - }, - { - type: 'ui_link', - id: 'AWS S3 based logs', - title: 'AWS S3 based logs', - categories: ['aws', 'cloud', 'datastore', 'security', 'network'], - uiInternalPath: '/app/home#/tutorial/awsLogs', - description: 'Collect AWS logs from S3 bucket with Filebeat.', - icons: [ - { - type: 'eui', - src: 'logoAWS', - }, - ], - shipper: 'beats', - eprOverlap: 'aws', - isBeta: false, - }, - { - type: 'ui_link', - id: 'ActiveMQ logs', - title: 'ActiveMQ logs', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/activemqLogs', - description: 'Collect ActiveMQ logs with Filebeat.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/activemq.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'activemq', - isBeta: false, - }, - { - type: 'ui_link', - id: 'ActiveMQ metrics', - title: 'ActiveMQ metrics', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/activemqMetrics', - description: 'Fetch monitoring metrics from ActiveMQ instances.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/activemq.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'activemq', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Azure metrics', - title: 'Azure metrics', - categories: ['azure', 'cloud', 'network', 'security'], - uiInternalPath: '/app/home#/tutorial/azureMetrics', - description: 'Fetch Azure Monitor metrics.', - icons: [ - { - type: 'eui', - src: 'logoAzure', - }, - ], - shipper: 'beats', - eprOverlap: 'azure', - isBeta: false, - }, - { - type: 'ui_link', - id: 'IBM MQ logs', - title: 'IBM MQ logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/ibmmqLogs', - description: 'Collect IBM MQ logs with Filebeat.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/ibmmq.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'ibmmq', - isBeta: false, - }, - { - type: 'ui_link', - id: 'IBM MQ metrics', - title: 'IBM MQ metrics', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/ibmmqMetrics', - description: 'Fetch monitoring metrics from IBM MQ instances.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/ibmmq.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'ibmmq', - isBeta: false, - }, - { - type: 'ui_link', - id: 'STAN metrics', - title: 'STAN metrics', - categories: ['message_queue', 'kubernetes'], - uiInternalPath: '/app/home#/tutorial/stanMetrics', - description: 'Fetch monitoring metrics from the STAN server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/stan.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'stan', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Envoy Proxy metrics', - title: 'Envoy Proxy metrics', - categories: ['elastic_stack', 'datastore'], - uiInternalPath: '/app/home#/tutorial/envoyproxyMetrics', - description: 'Fetch monitoring metrics from Envoy Proxy.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/envoyproxy.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'envoyproxy', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Statsd metrics', - title: 'Statsd metrics', - categories: ['message_queue', 'kubernetes'], - uiInternalPath: '/app/home#/tutorial/statsdMetrics', - description: 'Fetch monitoring metrics from statsd.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/statsd.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'statsd', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Redis Enterprise metrics', - title: 'Redis Enterprise metrics', - categories: ['datastore', 'message_queue'], - uiInternalPath: '/app/home#/tutorial/redisenterpriseMetrics', - description: 'Fetch monitoring metrics from Redis Enterprise Server.', - icons: [ - { - type: 'eui', - src: 'logoRedis', - }, - ], - shipper: 'beats', - eprOverlap: 'redisenterprise', - isBeta: false, - }, - { - type: 'ui_link', - id: 'OpenMetrics metrics', - title: 'OpenMetrics metrics', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/openmetricsMetrics', - description: 'Fetch metrics from an endpoint that serves metrics in OpenMetrics format.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/openmetrics.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'openmetrics', - isBeta: false, - }, - { - type: 'ui_link', - id: 'oracle metrics', - title: 'oracle metrics', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/oracleMetrics', - description: 'Fetch internal metrics from a Oracle server.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/oracle.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'oracle', - isBeta: false, - }, - { - type: 'ui_link', - id: 'IIS Metrics', - title: 'IIS Metrics', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/iisMetrics', - description: 'Collect IIS server related metrics.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/iis.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'iis', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Azure logs', - title: 'Azure logs', - categories: ['azure', 'cloud', 'network', 'security'], - uiInternalPath: '/app/home#/tutorial/azureLogs', - description: 'Collects Azure activity and audit related logs.', - icons: [ - { - type: 'eui', - src: 'logoAzure', - }, - ], - shipper: 'beats', - eprOverlap: 'azure', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Google Cloud metrics', - title: 'Google Cloud metrics', - categories: ['google_cloud', 'cloud', 'network', 'security'], - uiInternalPath: '/app/home#/tutorial/gcpMetrics', - description: - 'Fetch monitoring metrics from Google Cloud Platform using Stackdriver Monitoring API.', - icons: [ - { - type: 'eui', - src: 'logoGCP', - }, - ], - shipper: 'beats', - eprOverlap: 'gcp', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Auditd logs', - title: 'Auditd logs', - categories: ['os_system'], - uiInternalPath: '/app/home#/tutorial/auditdLogs', - description: 'Collect logs from the Linux auditd daemon.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/linux.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'auditd', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Barracuda logs', - title: 'Barracuda logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/barracudaLogs', - description: 'Collect Barracuda Web Application Firewall logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/barracuda.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'barracuda', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Bluecoat logs', - title: 'Bluecoat logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/bluecoatLogs', - description: 'Collect Blue Coat Director logs over syslog or from a file.', - icons: [ - { - type: 'eui', - src: 'logoLogging', - }, - ], - shipper: 'beats', - eprOverlap: 'bluecoat', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CEF logs', - title: 'CEF logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/cefLogs', - description: 'Collect Common Event Format (CEF) log data over syslog.', - icons: [ - { - type: 'eui', - src: 'logoLogging', - }, - ], - shipper: 'beats', - eprOverlap: 'cef', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Check Point logs', - title: 'Check Point logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/checkpointLogs', - description: 'Collect Check Point firewall logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/checkpoint.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'checkpoint', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CrowdStrike logs', - title: 'CrowdStrike logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/crowdstrikeLogs', - description: 'Collect CrowdStrike Falcon logs using the Falcon SIEM Connector.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/crowdstrike.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'crowdstrike', - isBeta: false, - }, - { - type: 'ui_link', - id: 'CylancePROTECT logs', - title: 'CylancePROTECT logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/cylanceLogs', - description: 'Collect CylancePROTECT logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/cylance.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'cylance', - isBeta: false, - }, - { - type: 'ui_link', - id: 'F5 logs', - title: 'F5 logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/f5Logs', - description: 'Collect F5 Big-IP Access Policy Manager logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/f5.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'f5', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Fortinet logs', - title: 'Fortinet logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/fortinetLogs', - description: 'Collect Fortinet FortiOS logs over syslog.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/fortinet.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'fortinet', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Google Cloud logs', - title: 'Google Cloud logs', - categories: ['google_cloud', 'cloud', 'network', 'security'], - uiInternalPath: '/app/home#/tutorial/gcpLogs', - description: 'Collect Google Cloud audit, firewall, and VPC flow logs.', - icons: [ - { - type: 'eui', - src: 'logoGoogleG', - }, - ], - shipper: 'beats', - eprOverlap: 'gcp', - isBeta: false, - }, - { - type: 'ui_link', - id: 'GSuite logs', - title: 'GSuite logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/gsuiteLogs', - description: 'Collect GSuite activity reports.', - icons: [ - { - type: 'eui', - src: 'logoGoogleG', - }, - ], - shipper: 'beats', - eprOverlap: 'gsuite', - isBeta: false, - }, - { - type: 'ui_link', - id: 'HAProxy logs', - title: 'HAProxy logs', - categories: ['network', 'web'], - uiInternalPath: '/app/home#/tutorial/haproxyLogs', - description: 'Collect HAProxy logs.', - icons: [ - { - type: 'eui', - src: 'logoHAproxy', - }, - ], - shipper: 'beats', - eprOverlap: 'haproxy', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Icinga logs', - title: 'Icinga logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/icingaLogs', - description: 'Collect Icinga main, debug, and startup logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/icinga.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'icinga', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Imperva logs', - title: 'Imperva logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/impervaLogs', - description: 'Collect Imperva SecureSphere logs over syslog or from a file.', - icons: [ - { - type: 'eui', - src: 'logoLogging', - }, - ], - shipper: 'beats', - eprOverlap: 'imperva', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Infoblox logs', - title: 'Infoblox logs', - categories: ['network'], - uiInternalPath: '/app/home#/tutorial/infobloxLogs', - description: 'Collect Infoblox NIOS logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/infoblox.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'infoblox', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Juniper Logs', - title: 'Juniper Logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/juniperLogs', - description: 'Collect Juniper JUNOS logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/juniper.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'juniper', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Kibana Logs', - title: 'Kibana Logs', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/kibanaLogs', - description: 'Collect Kibana logs.', - icons: [ - { - type: 'eui', - src: 'logoKibana', - }, - ], - shipper: 'beats', - eprOverlap: 'kibana', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Microsoft Defender ATP logs', - title: 'Microsoft Defender ATP logs', - categories: ['network', 'security', 'azure'], - uiInternalPath: '/app/home#/tutorial/microsoftLogs', - description: 'Collect Microsoft Defender ATP alerts.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/microsoft.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'microsoft', - isBeta: false, - }, - { - type: 'ui_link', - id: 'MISP threat intel logs', - title: 'MISP threat intel logs', - categories: ['network', 'security', 'azure'], - uiInternalPath: '/app/home#/tutorial/mispLogs', - description: 'Collect MISP threat intelligence data with Filebeat.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/misp.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'misp', - isBeta: false, - }, - { - type: 'ui_link', - id: 'MongoDB logs', - title: 'MongoDB logs', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/mongodbLogs', - description: 'Collect MongoDB logs.', - icons: [ - { - type: 'eui', - src: 'logoMongodb', - }, - ], - shipper: 'beats', - eprOverlap: 'mongodb', - isBeta: false, - }, - { - type: 'ui_link', - id: 'MSSQL logs', - title: 'MSSQL logs', - categories: ['datastore'], - uiInternalPath: '/app/home#/tutorial/mssqlLogs', - description: 'Collect MSSQL logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/microsoft.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'mssql', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Arbor Peakflow logs', - title: 'Arbor Peakflow logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/netscoutLogs', - description: 'Collect Netscout Arbor Peakflow SP logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/netscout.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'netscout', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Office 365 logs', - title: 'Office 365 logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/o365Logs', - description: 'Collect Office 365 activity logs via the Office 365 API.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/o365.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'o365', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Okta logs', - title: 'Okta logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/oktaLogs', - description: 'Collect the Okta system log via the Okta API.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/okta.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'okta', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Palo Alto Networks PAN-OS logs', - title: 'Palo Alto Networks PAN-OS logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/panwLogs', - description: - 'Collect Palo Alto Networks PAN-OS threat and traffic logs over syslog or from a log file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/paloalto.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'panw', - isBeta: false, - }, - { - type: 'ui_link', - id: 'RabbitMQ logs', - title: 'RabbitMQ logs', - categories: ['message_queue'], - uiInternalPath: '/app/home#/tutorial/rabbitmqLogs', - description: 'Collect RabbitMQ logs.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/rabbitmq.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'rabbitmq', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Radware DefensePro logs', - title: 'Radware DefensePro logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/radwareLogs', - description: 'Collect Radware DefensePro logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/radware.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'radware', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Google Santa logs', - title: 'Google Santa logs', - categories: ['security', 'os_system'], - uiInternalPath: '/app/home#/tutorial/santaLogs', - description: 'Collect Google Santa logs about process executions on MacOS.', - icons: [ - { - type: 'eui', - src: 'logoLogging', - }, - ], - shipper: 'beats', - eprOverlap: 'santa', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Sonicwall FW logs', - title: 'Sonicwall FW logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/sonicwallLogs', - description: 'Collect Sonicwall-FW logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/sonicwall.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'sonicwall', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Sophos logs', - title: 'Sophos logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/sophosLogs', - description: 'Collect Sophos XG SFOS logs over syslog.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/sophos.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'sophos', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Squid logs', - title: 'Squid logs', - categories: ['security'], - uiInternalPath: '/app/home#/tutorial/squidLogs', - description: 'Collect Squid logs over syslog or from a file.', - icons: [ - { - type: 'eui', - src: 'logoLogging', - }, - ], - shipper: 'beats', - eprOverlap: 'squid', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Tomcat logs', - title: 'Tomcat logs', - categories: ['web', 'security'], - uiInternalPath: '/app/home#/tutorial/tomcatLogs', - description: 'Collect Apache Tomcat logs over syslog or from a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/tomcat.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'tomcat', - isBeta: false, - }, - { - type: 'ui_link', - id: 'Zscaler Logs', - title: 'Zscaler Logs', - categories: ['network', 'security'], - uiInternalPath: '/app/home#/tutorial/zscalerLogs', - description: 'This is a module for receiving Zscaler NSS logs over Syslog or a file.', - icons: [ - { - type: 'svg', - src: '/dqo/plugins/home/assets/logos/zscaler.svg', - }, - ], - shipper: 'beats', - eprOverlap: 'zscaler', - isBeta: false, - }, - { - type: 'ui_link', - id: 'apm', - title: 'APM', - categories: ['web'], - uiInternalPath: '/app/home#/tutorial/apm', - description: 'Collect in-depth performance metrics and errors from inside your applications.', - icons: [ - { - type: 'eui', - src: 'apmApp', - }, - ], - shipper: 'tutorial', - isBeta: false, - eprOverlap: 'apm', + uiInternalPath: '/', + eprOverlap: 'exp_beats', }, ]; diff --git a/src/plugins/custom_integrations/server/index.ts b/src/plugins/custom_integrations/server/index.ts index 490627ef90f8d..00372df501435 100755 --- a/src/plugins/custom_integrations/server/index.ts +++ b/src/plugins/custom_integrations/server/index.ts @@ -19,7 +19,7 @@ export function plugin(initializerContext: PluginInitializerContext) { export { CustomIntegrationsPluginSetup, CustomIntegrationsPluginStart } from './types'; -export type { IntegrationCategory, IntegrationCategoryCount, CustomIntegration } from '../common'; +export type { IntegrationCategory, CustomIntegration } from '../common'; export const config = { schema: schema.object({}), diff --git a/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx b/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx index e6a2c41fd4ecb..712c070e17b9f 100644 --- a/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx +++ b/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx @@ -543,7 +543,6 @@ export function DashboardTopNav({ createType: title, onClick: createNewVisType(visType as VisTypeAlias), 'data-test-subj': `dashboardQuickButton${name}`, - isDarkModeEnabled: IS_DARK_THEME, }; } else { const { name, icon, title, titleInWizard } = visType as BaseVisType; @@ -553,7 +552,6 @@ export function DashboardTopNav({ createType: titleInWizard || title, onClick: createNewVisType(visType as BaseVisType), 'data-test-subj': `dashboardQuickButton${name}`, - isDarkModeEnabled: IS_DARK_THEME, }; } } diff --git a/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx b/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx index 46ae4d9456d92..8a46a16c1bf0c 100644 --- a/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx +++ b/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx @@ -238,16 +238,18 @@ export const EditorMenu = ({ dashboardContainer, createNewVisType }: Props) => { panelPaddingSize="none" data-test-subj="dashboardEditorMenuButton" > - <EuiContextMenu - initialPanelId={0} - panels={editorMenuPanels} - className={`dshSolutionToolbar__editorContextMenu ${ - IS_DARK_THEME - ? 'dshSolutionToolbar__editorContextMenu--dark' - : 'dshSolutionToolbar__editorContextMenu--light' - }`} - data-test-subj="dashboardEditorContextMenu" - /> + {() => ( + <EuiContextMenu + initialPanelId={0} + panels={editorMenuPanels} + className={`dshSolutionToolbar__editorContextMenu ${ + IS_DARK_THEME + ? 'dshSolutionToolbar__editorContextMenu--dark' + : 'dshSolutionToolbar__editorContextMenu--light' + }`} + data-test-subj="dashboardEditorContextMenu" + /> + )} </SolutionToolbarPopover> ); }; diff --git a/src/plugins/data/common/search/tabify/__snapshots__/tabify_docs.test.ts.snap b/src/plugins/data/common/search/tabify/__snapshots__/tabify_docs.test.ts.snap index 22276335a0599..9a85ba57ce5ef 100644 --- a/src/plugins/data/common/search/tabify/__snapshots__/tabify_docs.test.ts.snap +++ b/src/plugins/data/common/search/tabify/__snapshots__/tabify_docs.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`tabifyDocs combines meta fields if meta option is set 1`] = ` +exports[`tabify_docs tabifyDocs converts fields by default 1`] = ` Object { "columns": Array [ Object { @@ -108,7 +108,7 @@ Object { } `; -exports[`tabifyDocs converts fields by default 1`] = ` +exports[`tabify_docs tabifyDocs converts source if option is set 1`] = ` Object { "columns": Array [ Object { @@ -216,7 +216,7 @@ Object { } `; -exports[`tabifyDocs converts source if option is set 1`] = ` +exports[`tabify_docs tabifyDocs skips nested fields if option is set 1`] = ` Object { "columns": Array [ Object { @@ -324,115 +324,7 @@ Object { } `; -exports[`tabifyDocs skips nested fields if option is set 1`] = ` -Object { - "columns": Array [ - Object { - "id": "fieldTest", - "meta": Object { - "field": "fieldTest", - "index": "test-index", - "params": Object { - "id": "number", - }, - "type": "number", - }, - "name": "fieldTest", - }, - Object { - "id": "invalidMapping", - "meta": Object { - "field": "invalidMapping", - "index": "test-index", - "params": undefined, - "type": "number", - }, - "name": "invalidMapping", - }, - Object { - "id": "nested", - "meta": Object { - "field": "nested", - "index": "test-index", - "params": undefined, - "type": "object", - }, - "name": "nested", - }, - Object { - "id": "sourceTest", - "meta": Object { - "field": "sourceTest", - "index": "test-index", - "params": Object { - "id": "number", - }, - "type": "number", - }, - "name": "sourceTest", - }, - Object { - "id": "_id", - "meta": Object { - "field": "_id", - "index": "test-index", - "params": undefined, - "type": "string", - }, - "name": "_id", - }, - Object { - "id": "_index", - "meta": Object { - "field": "_index", - "index": "test-index", - "params": undefined, - "type": "string", - }, - "name": "_index", - }, - Object { - "id": "_score", - "meta": Object { - "field": "_score", - "index": "test-index", - "params": undefined, - "type": "number", - }, - "name": "_score", - }, - Object { - "id": "_type", - "meta": Object { - "field": "_type", - "index": "test-index", - "params": undefined, - "type": "string", - }, - "name": "_type", - }, - ], - "rows": Array [ - Object { - "_id": "hit-id-value", - "_index": "hit-index-value", - "_score": 77, - "_type": "hit-type-value", - "fieldTest": 123, - "invalidMapping": 345, - "nested": Array [ - Object { - "field": 123, - }, - ], - "sourceTest": 123, - }, - ], - "type": "datatable", -} -`; - -exports[`tabifyDocs works without provided index pattern 1`] = ` +exports[`tabify_docs tabifyDocs works without provided index pattern 1`] = ` Object { "columns": Array [ Object { @@ -475,53 +367,9 @@ Object { }, "name": "sourceTest", }, - Object { - "id": "_id", - "meta": Object { - "field": "_id", - "index": undefined, - "params": undefined, - "type": "string", - }, - "name": "_id", - }, - Object { - "id": "_index", - "meta": Object { - "field": "_index", - "index": undefined, - "params": undefined, - "type": "string", - }, - "name": "_index", - }, - Object { - "id": "_score", - "meta": Object { - "field": "_score", - "index": undefined, - "params": undefined, - "type": "number", - }, - "name": "_score", - }, - Object { - "id": "_type", - "meta": Object { - "field": "_type", - "index": undefined, - "params": undefined, - "type": "string", - }, - "name": "_type", - }, ], "rows": Array [ Object { - "_id": "hit-id-value", - "_index": "hit-index-value", - "_score": 77, - "_type": "hit-type-value", "fieldTest": 123, "invalidMapping": 345, "nested": Array [ diff --git a/src/plugins/data/common/search/tabify/index.ts b/src/plugins/data/common/search/tabify/index.ts index 74fbc7ba4cfa4..279ff705f231c 100644 --- a/src/plugins/data/common/search/tabify/index.ts +++ b/src/plugins/data/common/search/tabify/index.ts @@ -6,6 +6,6 @@ * Side Public License, v 1. */ -export { tabifyDocs } from './tabify_docs'; +export { tabifyDocs, flattenHit } from './tabify_docs'; export { tabifyAggResponse } from './tabify'; export { tabifyGetColumns } from './get_columns'; diff --git a/src/plugins/data/common/search/tabify/tabify_docs.test.ts b/src/plugins/data/common/search/tabify/tabify_docs.test.ts index 1a3f7195b722e..a2910a1be4a9a 100644 --- a/src/plugins/data/common/search/tabify/tabify_docs.test.ts +++ b/src/plugins/data/common/search/tabify/tabify_docs.test.ts @@ -6,71 +6,137 @@ * Side Public License, v 1. */ -import { tabifyDocs } from './tabify_docs'; -import { IndexPattern } from '../..'; +import { tabifyDocs, flattenHit } from './tabify_docs'; +import { IndexPattern, DataView } from '../..'; import type { estypes } from '@elastic/elasticsearch'; -describe('tabifyDocs', () => { - const fieldFormats = { - getInstance: (id: string) => ({ toJSON: () => ({ id }) }), - getDefaultInstance: (id: string) => ({ toJSON: () => ({ id }) }), - }; +import { fieldFormatsMock } from '../../../../field_formats/common/mocks'; +import { stubbedSavedObjectIndexPattern } from '../../../../data_views/common/data_view.stub'; - const index = new IndexPattern({ +class MockFieldFormatter {} + +fieldFormatsMock.getInstance = jest.fn().mockImplementation(() => new MockFieldFormatter()) as any; + +// helper function to create index patterns +function create(id: string) { + const { + type, + version, + attributes: { timeFieldName, fields, title }, + } = stubbedSavedObjectIndexPattern(id); + + return new DataView({ spec: { - id: 'test-index', - fields: { - sourceTest: { name: 'sourceTest', type: 'number', searchable: true, aggregatable: true }, - fieldTest: { name: 'fieldTest', type: 'number', searchable: true, aggregatable: true }, - 'nested.field': { - name: 'nested.field', - type: 'number', - searchable: true, - aggregatable: true, - }, - }, + id, + type, + version, + timeFieldName, + fields: JSON.parse(fields), + title, + runtimeFieldMap: {}, }, - fieldFormats: fieldFormats as any, + fieldFormats: fieldFormatsMock, + shortDotsEnable: false, + metaFields: ['_id', '_type', '_score', '_routing'], }); +} - // @ts-expect-error not full inteface - const response = { - hits: { - hits: [ +describe('tabify_docs', () => { + describe('flattenHit', () => { + let indexPattern: DataView; + + // create an indexPattern instance for each test + beforeEach(() => { + indexPattern = create('test-pattern'); + }); + + it('returns sorted object keys that combine _source, fields and metaFields in a defined order', () => { + const response = flattenHit( { - _id: 'hit-id-value', - _index: 'hit-index-value', - _type: 'hit-type-value', - _score: 77, - _source: { sourceTest: 123 }, - fields: { fieldTest: 123, invalidMapping: 345, nested: [{ field: 123 }] }, + _index: 'foobar', + _id: 'a', + _source: { + name: 'first', + }, + fields: { + date: ['1'], + zzz: ['z'], + _abc: ['a'], + }, }, - ], - }, - } as estypes.SearchResponse<unknown>; - - it('converts fields by default', () => { - const table = tabifyDocs(response, index); - expect(table).toMatchSnapshot(); + indexPattern + ); + const expectedOrder = ['_abc', 'date', 'name', 'zzz', '_id', '_routing', '_score', '_type']; + expect(Object.keys(response)).toEqual(expectedOrder); + expect(Object.entries(response).map(([key]) => key)).toEqual(expectedOrder); + }); }); - it('converts source if option is set', () => { - const table = tabifyDocs(response, index, { source: true }); - expect(table).toMatchSnapshot(); - }); + describe('tabifyDocs', () => { + const fieldFormats = { + getInstance: (id: string) => ({ toJSON: () => ({ id }) }), + getDefaultInstance: (id: string) => ({ toJSON: () => ({ id }) }), + }; - it('skips nested fields if option is set', () => { - const table = tabifyDocs(response, index, { shallow: true }); - expect(table).toMatchSnapshot(); - }); + const index = new IndexPattern({ + spec: { + id: 'test-index', + fields: { + sourceTest: { name: 'sourceTest', type: 'number', searchable: true, aggregatable: true }, + fieldTest: { name: 'fieldTest', type: 'number', searchable: true, aggregatable: true }, + 'nested.field': { + name: 'nested.field', + type: 'number', + searchable: true, + aggregatable: true, + }, + }, + }, + metaFields: ['_id', '_index', '_score', '_type'], + fieldFormats: fieldFormats as any, + }); - it('combines meta fields if meta option is set', () => { - const table = tabifyDocs(response, index, { meta: true }); - expect(table).toMatchSnapshot(); - }); + // @ts-expect-error not full inteface + const response = { + hits: { + hits: [ + { + _id: 'hit-id-value', + _index: 'hit-index-value', + _type: 'hit-type-value', + _score: 77, + _source: { sourceTest: 123 }, + fields: { fieldTest: 123, invalidMapping: 345, nested: [{ field: 123 }] }, + }, + ], + }, + } as estypes.SearchResponse<unknown>; + + it('converts fields by default', () => { + const table = tabifyDocs(response, index); + expect(table).toMatchSnapshot(); + }); + + it('converts source if option is set', () => { + const table = tabifyDocs(response, index, { source: true }); + expect(table).toMatchSnapshot(); + }); + + it('skips nested fields if option is set', () => { + const table = tabifyDocs(response, index, { shallow: true }); + expect(table).toMatchSnapshot(); + }); + + it('combines meta fields from index pattern', () => { + const table = tabifyDocs(response, index); + expect(table.columns.map((col) => col.id)).toEqual( + expect.arrayContaining(['_id', '_index', '_score', '_type']) + ); + }); - it('works without provided index pattern', () => { - const table = tabifyDocs(response); - expect(table).toMatchSnapshot(); + it('works without provided index pattern', () => { + const table = tabifyDocs(response); + expect(table).toMatchSnapshot(); + }); }); }); diff --git a/src/plugins/data/common/search/tabify/tabify_docs.ts b/src/plugins/data/common/search/tabify/tabify_docs.ts index 8e628e7741df5..4259488771761 100644 --- a/src/plugins/data/common/search/tabify/tabify_docs.ts +++ b/src/plugins/data/common/search/tabify/tabify_docs.ts @@ -11,12 +11,60 @@ import { isPlainObject } from 'lodash'; import { IndexPattern } from '../..'; import { Datatable, DatatableColumn, DatatableColumnType } from '../../../../expressions/common'; +type ValidMetaFieldNames = keyof Pick< + estypes.SearchHit, + | '_id' + | '_ignored' + | '_index' + | '_node' + | '_primary_term' + | '_routing' + | '_score' + | '_seq_no' + | '_shard' + | '_source' + | '_type' + | '_version' +>; +const VALID_META_FIELD_NAMES: ValidMetaFieldNames[] = [ + '_id', + '_ignored', + '_index', + '_node', + '_primary_term', + '_routing', + '_score', + '_seq_no', + '_shard', + '_source', + '_type', + '_version', +]; + +function isValidMetaFieldName(field: string): field is ValidMetaFieldNames { + // Since the array above is more narrowly typed than string[], we cannot use + // string to find a value in here. We manually cast it to wider string[] type + // so we're able to use `includes` on it. + return (VALID_META_FIELD_NAMES as string[]).includes(field); +} + export interface TabifyDocsOptions { shallow?: boolean; + /** + * If set to `false` the _source of the document, if requested, won't be + * merged into the flattened document. + */ source?: boolean; - meta?: boolean; } +/** + * Flattens an individual hit (from an ES response) into an object. This will + * create flattened field names, like `user.name`. + * + * @param hit The hit from an ES reponse's hits.hits[] + * @param indexPattern The index pattern for the requested index if available. + * @param params Parameters how to flatten the hit + */ export function flattenHit( hit: estypes.SearchHit, indexPattern?: IndexPattern, @@ -62,13 +110,36 @@ export function flattenHit( if (params?.source !== false && hit._source) { flatten(hit._source as Record<string, any>); } - if (params?.meta !== false) { - // combine the fields that Discover allows to add as columns - const { _id, _index, _type, _score } = hit; - flatten({ _id, _index, _score, _type }); - } - return flat; + // Merge all valid meta fields into the flattened object + // expect for _source (in case that was specified as a meta field) + indexPattern?.metaFields?.forEach((metaFieldName) => { + if (!isValidMetaFieldName(metaFieldName) || metaFieldName === '_source') { + return; + } + flat[metaFieldName] = hit[metaFieldName]; + }); + + // Use a proxy to make sure that keys are always returned in a specific order, + // so we have a guarantee on the flattened order of keys. + return new Proxy(flat, { + ownKeys: (target) => { + return Reflect.ownKeys(target).sort((a, b) => { + const aIsMeta = indexPattern?.metaFields?.includes(String(a)); + const bIsMeta = indexPattern?.metaFields?.includes(String(b)); + if (aIsMeta && bIsMeta) { + return String(a).localeCompare(String(b)); + } + if (aIsMeta) { + return 1; + } + if (bIsMeta) { + return -1; + } + return String(a).localeCompare(String(b)); + }); + }, + }); } export const tabifyDocs = ( diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 3ae98c083976e..4d51a7ae0ad77 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -52,7 +52,6 @@ import { ILLEGAL_CHARACTERS_VISIBLE, ILLEGAL_CHARACTERS, validateDataView, - flattenHitWrapper, } from './data_views'; export type { IndexPatternsService } from './data_views'; @@ -69,7 +68,6 @@ export const indexPatterns = { getFieldSubtypeMulti, getFieldSubtypeNested, validate: validateDataView, - flattenHitWrapper, }; export { diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/filter_editor.test.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/filter_editor.test.tsx index 4760968b65539..3a0c0db96c5de 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/filter_editor.test.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/filter_editor.test.tsx @@ -10,14 +10,14 @@ import { registerTestBed, TestBed } from '@kbn/test/jest'; import { FilterEditor, Props } from '.'; import React from 'react'; -jest.mock('@elastic/eui', () => { - const original = jest.requireActual('@elastic/eui'); +jest.mock('../../../../../kibana_react/public', () => { + const original = jest.requireActual('../../../../../kibana_react/public'); return { ...original, - EuiCodeEditor: (props: any) => ( + CodeEditor: (props: any) => ( <input - data-test-subj={props['data-test-subj'] || 'mockEuiCodeEditor'} + data-test-subj={props['data-test-subj'] || 'mockCodeEditor'} value={props.value} onChange={async (eve: any) => { props.onChange(eve.target.value); diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx index 9bf090b8240a6..aeff61739be4d 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx @@ -9,8 +9,6 @@ import { EuiButton, EuiButtonEmpty, - // @ts-ignore - EuiCodeEditor, EuiFieldText, EuiFlexGroup, EuiFlexItem, @@ -33,6 +31,7 @@ import { } from '@kbn/es-query'; import { get } from 'lodash'; import React, { Component } from 'react'; +import { XJsonLang } from '@kbn/monaco'; import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; import { getFieldFromFilter, @@ -47,6 +46,7 @@ import { PhrasesValuesInput } from './phrases_values_input'; import { RangeValueInput } from './range_value_input'; import { getIndexPatternFromFilter } from '../../../query'; import { IIndexPattern, IFieldType } from '../../..'; +import { CodeEditor } from '../../../../../kibana_react/public'; export interface Props { filter: Filter; @@ -328,13 +328,16 @@ class FilterEditorUI extends Component<Props, State> { defaultMessage: 'Elasticsearch Query DSL', })} > - <EuiCodeEditor + <CodeEditor + languageId={XJsonLang.ID} + width="100%" + height={'250px'} value={this.state.queryDsl} onChange={this.onQueryDslChange} - mode="json" - width="100%" - height="250px" data-test-subj="customEditorInput" + aria-label={i18n.translate('data.filter.filterEditor.queryDslAriaLabel', { + defaultMessage: 'Elasticsearch Query DSL editor', + })} /> </EuiFormRow> ); diff --git a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap index 9cd0687a1074d..eae2032748396 100644 --- a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap @@ -884,7 +884,12 @@ exports[`Inspector Data View component should render single table without select }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } onChange={[Function]} pagination={ Object { @@ -2449,7 +2454,12 @@ exports[`Inspector Data View component should support multiple datatables 1`] = }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } onChange={[Function]} pagination={ Object { diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts index 284a381f063dd..19ecde71e6a19 100644 --- a/src/plugins/data/server/ui_settings.ts +++ b/src/plugins/data/server/ui_settings.ts @@ -269,6 +269,12 @@ export function getUiSettings(): Record<string, UiSettingsParams<unknown>> { target="_blank" rel="noopener">frozen indices</a> in results if enabled. Searching through frozen indices might increase the search time.`, value: false, + deprecation: { + message: i18n.translate('data.advancedSettings.search.includeFrozenTextDeprecation', { + defaultMessage: 'This setting is deprecated and will be removed in Kibana 9.0.', + }), + docLinksKey: 'kibanaSearchSettings', + }, category: ['search'], schema: schema.boolean(), }, diff --git a/src/plugins/data_views/common/data_views/data_view.ts b/src/plugins/data_views/common/data_views/data_view.ts index 5768ebe635729..57db127208dc3 100644 --- a/src/plugins/data_views/common/data_views/data_view.ts +++ b/src/plugins/data_views/common/data_views/data_view.ts @@ -72,6 +72,9 @@ export class DataView implements IIndexPattern { formatField: FormatFieldFn; }; public formatField: FormatFieldFn; + /** + * @deprecated Use `flattenHit` utility method exported from data plugin instead. + */ public flattenHit: (hit: Record<string, any>, deep?: boolean) => Record<string, any>; public metaFields: string[]; /** diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts index 9a01e52ce48e2..210c926f92df7 100644 --- a/src/plugins/data_views/common/data_views/data_views.test.ts +++ b/src/plugins/data_views/common/data_views/data_views.test.ts @@ -50,9 +50,15 @@ describe('IndexPatterns', () => { let indexPatterns: DataViewsService; let savedObjectsClient: SavedObjectsClientCommon; let SOClientGetDelay = 0; + const uiSettings = { + get: () => Promise.resolve(false), + getAll: () => {}, + set: () => () => {}, + remove: jest.fn(), + } as any as UiSettingsCommon; + const indexPatternObj = { id: 'id', version: 'a', attributes: { title: 'title' } }; beforeEach(() => { - const indexPatternObj = { id: 'id', version: 'a', attributes: { title: 'title' } }; savedObjectsClient = {} as SavedObjectsClientCommon; savedObjectsClient.find = jest.fn( () => Promise.resolve([indexPatternObj]) as Promise<Array<SavedObject<any>>> @@ -86,10 +92,7 @@ describe('IndexPatterns', () => { }); indexPatterns = new DataViewsService({ - uiSettings: { - get: () => Promise.resolve(false), - getAll: () => {}, - } as any as UiSettingsCommon, + uiSettings, savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientCommon, apiClient: createFieldsFetcher(), fieldFormats, @@ -274,4 +277,49 @@ describe('IndexPatterns', () => { // successful subsequent request expect(async () => await indexPatterns.get(id)).toBeDefined(); }); + + describe('getDefaultDataView', () => { + test('gets default data view', async () => { + indexPatterns.clearCache(); + jest.clearAllMocks(); + + expect(await indexPatterns.getDefaultDataView()).toBeInstanceOf(DataView); + // make sure we're not pulling from cache + expect(savedObjectsClient.get).toBeCalledTimes(1); + expect(savedObjectsClient.find).toBeCalledTimes(1); + }); + + test('returns undefined if no data views exist', async () => { + savedObjectsClient.find = jest.fn( + () => Promise.resolve([]) as Promise<Array<SavedObject<any>>> + ); + savedObjectsClient.get = jest.fn(() => Promise.resolve(undefined) as Promise<any>); + indexPatterns.clearCache(); + expect(await indexPatterns.getDefaultDataView()).toBeUndefined(); + }); + + test("default doesn't exist, grabs another data view", async () => { + indexPatterns.clearCache(); + jest.clearAllMocks(); + uiSettings.get = jest.fn().mockResolvedValue(['bar']); + + savedObjectsClient.find = jest.fn( + () => Promise.resolve([indexPatternObj]) as Promise<Array<SavedObject<any>>> + ); + + savedObjectsClient.get = jest.fn().mockResolvedValue({ + id: 'bar', + version: 'foo', + attributes: { + title: 'something', + }, + }); + + expect(await indexPatterns.getDefaultDataView()).toBeInstanceOf(DataView); + // make sure we're not pulling from cache + expect(savedObjectsClient.get).toBeCalledTimes(1); + expect(savedObjectsClient.find).toBeCalledTimes(1); + expect(uiSettings.remove).toBeCalledTimes(1); + }); + }); }); diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index 77ce1caaaad84..a76b531668162 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -79,6 +79,10 @@ export class DataViewsService { private onError: OnError; private dataViewCache: ReturnType<typeof createDataViewCache>; + /** + * @deprecated Use `getDefaultDataView` instead (when loading data view) and handle + * 'no data view' case in api consumer code - no more auto redirect + */ ensureDefaultDataView: EnsureDefaultDataView; constructor({ @@ -681,6 +685,33 @@ export class DataViewsService { this.dataViewCache.clear(indexPatternId); return this.savedObjectsClient.delete(DATA_VIEW_SAVED_OBJECT_TYPE, indexPatternId); } + + /** + * Returns the default data view as an object. If no default is found, or it is missing + * another data view is selected as default and returned. + * @returns default data view + */ + + async getDefaultDataView() { + const patterns = await this.getIds(); + let defaultId = await this.config.get('defaultIndex'); + let defined = !!defaultId; + const exists = patterns.includes(defaultId); + + if (defined && !exists) { + await this.config.remove('defaultIndex'); + defaultId = defined = false; + } + + if (patterns.length >= 1 && (await this.hasUserDataView().catch(() => true))) { + defaultId = patterns[0]; + await this.config.set('defaultIndex', defaultId); + } + + if (defaultId) { + return this.get(defaultId); + } + } } /** diff --git a/src/plugins/data_views/common/data_views/flatten_hit.ts b/src/plugins/data_views/common/data_views/flatten_hit.ts index ddf484affa298..0a6388f0914b1 100644 --- a/src/plugins/data_views/common/data_views/flatten_hit.ts +++ b/src/plugins/data_views/common/data_views/flatten_hit.ts @@ -6,6 +6,11 @@ * Side Public License, v 1. */ +// --------- DEPRECATED --------- +// This implementation of flattenHit is deprecated and should no longer be used. +// If you consider adding features to this, please don't but use the `flattenHit` +// implementation from the data plugin. + import _ from 'lodash'; import { DataView } from './data_view'; @@ -114,15 +119,3 @@ export function flattenHitWrapper(dataView: DataView, metaFields = {}, cache = n return decorateFlattened(flattened); }; } - -/** - * This wraps `flattenHitWrapper` so one single cache can be provided for all uses of that - * function. The returned value of this function is what is included in the index patterns - * setup contract. - * - * @public - */ -export function createFlattenHitWrapper() { - const cache = new WeakMap(); - return _.partial(flattenHitWrapper, _, _, cache); -} diff --git a/src/plugins/data_views/public/index.ts b/src/plugins/data_views/public/index.ts index 572806df11fa3..5c810ec1fd4c8 100644 --- a/src/plugins/data_views/public/index.ts +++ b/src/plugins/data_views/public/index.ts @@ -13,7 +13,7 @@ export { ILLEGAL_CHARACTERS, validateDataView, } from '../common/lib'; -export { flattenHitWrapper, formatHitProvider, onRedirectNoIndexPattern } from './data_views'; +export { formatHitProvider, onRedirectNoIndexPattern } from './data_views'; export { IndexPatternField, IIndexPatternFieldList, TypeMeta } from '../common'; diff --git a/src/plugins/discover/kibana.json b/src/plugins/discover/kibana.json index 46eeb5af1470d..3d5fdefd276d3 100644 --- a/src/plugins/discover/kibana.json +++ b/src/plugins/discover/kibana.json @@ -15,8 +15,8 @@ "savedObjects", "indexPatternFieldEditor" ], - "optionalPlugins": ["home", "share", "usageCollection"], - "requiredBundles": ["kibanaUtils", "home", "kibanaReact", "fieldFormats"], + "optionalPlugins": ["home", "share", "usageCollection", "spaces"], + "requiredBundles": ["kibanaUtils", "home", "kibanaReact", "fieldFormats", "dataViews"], "extraPublicDirs": ["common"], "owner": { "name": "Data Discovery", diff --git a/src/plugins/discover/public/__mocks__/index_pattern.ts b/src/plugins/discover/public/__mocks__/index_pattern.ts index f9cc202f9063e..2acb512617a6b 100644 --- a/src/plugins/discover/public/__mocks__/index_pattern.ts +++ b/src/plugins/discover/public/__mocks__/index_pattern.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import { IIndexPatternFieldList } from '../../../data/common'; +import type { estypes } from '@elastic/elasticsearch'; +import { flattenHit, IIndexPatternFieldList } from '../../../data/common'; import { IndexPattern } from '../../../data/common'; -import { indexPatterns } from '../../../data/public'; const fields = [ { @@ -85,10 +85,11 @@ const indexPattern = { getFormatterForField: () => ({ convert: () => 'formatted' }), } as unknown as IndexPattern; -indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields); indexPattern.isTimeBased = () => !!indexPattern.timeFieldName; indexPattern.formatField = (hit: Record<string, unknown>, fieldName: string) => { - return fieldName === '_source' ? hit._source : indexPattern.flattenHit(hit)[fieldName]; + return fieldName === '_source' + ? hit._source + : flattenHit(hit as unknown as estypes.SearchHit, indexPattern)[fieldName]; }; export const indexPatternMock = indexPattern; diff --git a/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts b/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts index 0f64a6c67741d..6cf8e8b3485ff 100644 --- a/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts +++ b/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import { IIndexPatternFieldList } from '../../../data/common'; +import { flattenHit, IIndexPatternFieldList } from '../../../data/common'; import { IndexPattern } from '../../../data/common'; -import { indexPatterns } from '../../../data/public'; +import type { estypes } from '@elastic/elasticsearch'; const fields = [ { @@ -76,10 +76,11 @@ const indexPattern = { popularizeField: () => {}, } as unknown as IndexPattern; -indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields); indexPattern.isTimeBased = () => !!indexPattern.timeFieldName; indexPattern.formatField = (hit: Record<string, unknown>, fieldName: string) => { - return fieldName === '_source' ? hit._source : indexPattern.flattenHit(hit)[fieldName]; + return fieldName === '_source' + ? hit._source + : flattenHit(hit as unknown as estypes.SearchHit, indexPattern)[fieldName]; }; export const indexPatternWithTimefieldMock = indexPattern; diff --git a/src/plugins/discover/public/__mocks__/saved_search.ts b/src/plugins/discover/public/__mocks__/saved_search.ts index ebe65a5770356..a488fe7e04c50 100644 --- a/src/plugins/discover/public/__mocks__/saved_search.ts +++ b/src/plugins/discover/public/__mocks__/saved_search.ts @@ -13,44 +13,10 @@ import { indexPatternWithTimefieldMock } from './index_pattern_with_timefield'; export const savedSearchMock = { id: 'the-saved-search-id', - type: 'search', - attributes: { - title: 'the-saved-search-title', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"highlightAll":true,"version":true,"query":{"query":"foo : \\"bar\\" ","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - }, - references: [ - { - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - id: 'the-index-pattern-id', - }, - ], - migrationVersion: { search: '7.5.0' }, - error: undefined, searchSource: createSearchSourceMock({ index: indexPatternMock }), } as unknown as SavedSearch; export const savedSearchMockWithTimeField = { id: 'the-saved-search-id-with-timefield', - type: 'search', - attributes: { - title: 'the-saved-search-title', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"highlightAll":true,"version":true,"query":{"query":"foo : \\"bar\\" ","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - }, - references: [ - { - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - id: 'the-index-pattern-id', - }, - ], - migrationVersion: { search: '7.5.0' }, - error: undefined, searchSource: createSearchSourceMock({ index: indexPatternWithTimefieldMock }), } as unknown as SavedSearch; diff --git a/src/plugins/discover/public/__mocks__/services.ts b/src/plugins/discover/public/__mocks__/services.ts index 30d66b113e528..8cc5ccf5aa121 100644 --- a/src/plugins/discover/public/__mocks__/services.ts +++ b/src/plugins/discover/public/__mocks__/services.ts @@ -16,7 +16,6 @@ import { SAMPLE_SIZE_SETTING, SORT_DEFAULT_ORDER_SETTING, } from '../../common'; -import { savedSearchMock } from './saved_search'; import { UI_SETTINGS } from '../../../data/common'; import { TopNavMenu } from '../../../navigation/public'; import { FORMATS_UI_SETTINGS } from 'src/plugins/field_formats/common'; @@ -78,7 +77,6 @@ export const discoverServiceMock = { editIndexPattern: jest.fn(), }, }, - getSavedSearchById: (id?: string) => Promise.resolve(savedSearchMock), navigation: { ui: { TopNavMenu }, }, diff --git a/src/plugins/discover/public/application/apps/context/services/context.ts b/src/plugins/discover/public/application/apps/context/services/context.ts index b76b5ac648c22..257ae2dcce834 100644 --- a/src/plugins/discover/public/application/apps/context/services/context.ts +++ b/src/plugins/discover/public/application/apps/context/services/context.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { Filter, IndexPattern, SearchSource } from 'src/plugins/data/public'; +import { Filter, IndexPattern, ISearchSource } from 'src/plugins/data/public'; import { reverseSortDir, SortDirection } from './utils/sorting'; import { convertIsoToMillis, extractNanos } from './utils/date_conversion'; import { fetchHitsInInterval } from './utils/fetch_hits_in_interval'; @@ -53,7 +53,7 @@ export async function fetchSurroundingDocs( } const { data } = getServices(); const timeField = indexPattern.timeFieldName!; - const searchSource = data.search.searchSource.createEmpty() as SearchSource; + const searchSource = data.search.searchSource.createEmpty(); updateSearchSource(searchSource, indexPattern, filters, Boolean(useNewFieldsApi)); const sortDirToApply = type === SurrDocType.SUCCESSORS ? sortDir : reverseSortDir(sortDir); @@ -104,7 +104,7 @@ export async function fetchSurroundingDocs( } export function updateSearchSource( - searchSource: SearchSource, + searchSource: ISearchSource, indexPattern: IndexPattern, filters: Filter[], useNewFieldsApi: boolean diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx index 8d56f2adeaf65..d91735460af08 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx @@ -10,6 +10,7 @@ import React, { Fragment, useCallback, useMemo, useState } from 'react'; import classNames from 'classnames'; import { i18n } from '@kbn/i18n'; import { EuiButtonEmpty, EuiIcon } from '@elastic/eui'; +import { flattenHit } from '../../../../../../../../data/common'; import { DocViewer } from '../../../../../components/doc_viewer/doc_viewer'; import { FilterManager, IndexPattern } from '../../../../../../../../data/public'; import { TableCell } from './table_row/table_cell'; @@ -57,7 +58,7 @@ export const TableRow = ({ }); const anchorDocTableRowSubj = row.isAnchor ? ' docTableAnchorRow' : ''; - const flattenedRow = useMemo(() => indexPattern.flattenHit(row), [indexPattern, row]); + const flattenedRow = useMemo(() => flattenHit(row, indexPattern), [indexPattern, row]); const mapping = useMemo(() => indexPattern.fields.getByName, [indexPattern]); // toggle display of the rows details, a full list of the fields from each row diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx index e0e0c9c6f8831..d6ede9aa7fe5f 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx @@ -134,7 +134,7 @@ function DiscoverDocumentsComponent({ sort={state.sort || []} isLoading={isLoading} searchDescription={savedSearch.description} - sharedItemTitle={savedSearch.lastSavedTitle} + sharedItemTitle={savedSearch.title} onAddColumn={onAddColumn} onFilter={onAddFilter as DocViewFilterFn} onMoveColumn={onMoveColumn} @@ -156,7 +156,7 @@ function DiscoverDocumentsComponent({ sort={(state.sort as SortPairArr[]) || []} sampleSize={sampleSize} searchDescription={savedSearch.description} - searchTitle={savedSearch.lastSavedTitle} + searchTitle={savedSearch.title} setExpandedDoc={setExpandedDoc} showTimeCol={showTimeCol} services={services} diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx index 4bbef32dcbadd..6c6393daf30a3 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx @@ -39,6 +39,10 @@ import { useDataGridColumns } from '../../../../helpers/use_data_grid_columns'; import { DiscoverDocuments } from './discover_documents'; import { FetchStatus } from '../../../../types'; import { useDataState } from '../../utils/use_data_state'; +import { + SavedSearchURLConflictCallout, + useSavedSearchAliasMatchRedirect, +} from '../../../../../saved_searches'; /** * Local storage key for sidebar persistence state @@ -65,10 +69,18 @@ export function DiscoverLayout({ state, stateContainer, }: DiscoverLayoutProps) { - const { trackUiMetric, capabilities, indexPatterns, data, uiSettings, filterManager, storage } = - services; + const { + trackUiMetric, + capabilities, + indexPatterns, + data, + uiSettings, + filterManager, + storage, + history, + spaces, + } = services; const { main$, charts$, totalHits$ } = savedSearchData$; - const [expandedDoc, setExpandedDoc] = useState<ElasticSearchHit | undefined>(undefined); const [inspectorSession, setInspectorSession] = useState<InspectorSession | undefined>(undefined); const fetchCounter = useRef<number>(0); @@ -80,6 +92,8 @@ export function DiscoverLayout({ } }, [dataState.fetchStatus]); + useSavedSearchAliasMatchRedirect({ savedSearch, spaces, history }); + const timeField = useMemo(() => { return indexPattern.type !== 'rollup' ? indexPattern.timeFieldName : undefined; }, [indexPattern]); @@ -174,6 +188,11 @@ export function DiscoverLayout({ resetSavedSearch={resetSavedSearch} /> <EuiPageBody className="dscPageBody" aria-describedby="savedSearchTitle"> + <SavedSearchURLConflictCallout + savedSearch={savedSearch} + spaces={spaces} + history={history} + /> <h1 id="savedSearchTitle" className="euiScreenReaderOnly"> {savedSearch.title} </h1> diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx index e53bf006e2b4e..a550dbd59b9fa 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx @@ -15,7 +15,7 @@ import realHits from '../../../../../__fixtures__/real_hits.js'; import { mountWithIntl } from '@kbn/test/jest'; import React from 'react'; import { DiscoverSidebarProps } from './discover_sidebar'; -import { IndexPatternAttributes } from '../../../../../../../data/common'; +import { flattenHit, IndexPatternAttributes } from '../../../../../../../data/common'; import { SavedObject } from '../../../../../../../../core/types'; import { getDefaultFieldFilter } from './lib/field_filter'; import { DiscoverSidebarComponent as DiscoverSidebar } from './discover_sidebar'; @@ -44,7 +44,7 @@ function getCompProps(): DiscoverSidebarProps { const fieldCounts: Record<string, number> = {}; for (const hit of hits) { - for (const key of Object.keys(indexPattern.flattenHit(hit))) { + for (const key of Object.keys(flattenHit(hit, indexPattern))) { fieldCounts[key] = (fieldCounts[key] || 0) + 1; } } diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx index 9d73f885c988d..ded7897d2a9e5 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx @@ -15,7 +15,7 @@ import realHits from '../../../../../__fixtures__/real_hits.js'; import { act } from 'react-dom/test-utils'; import { mountWithIntl } from '@kbn/test/jest'; import React from 'react'; -import { IndexPatternAttributes } from '../../../../../../../data/common'; +import { flattenHit, IndexPatternAttributes } from '../../../../../../../data/common'; import { SavedObject } from '../../../../../../../../core/types'; import { DiscoverSidebarResponsive, @@ -72,7 +72,7 @@ function getCompProps(): DiscoverSidebarResponsiveProps { const indexPattern = stubLogstashIndexPattern; // @ts-expect-error _.each() is passing additional args to flattenHit - const hits = each(cloneDeep(realHits), indexPattern.flattenHit) as Array< + const hits = each(cloneDeep(realHits), (hit) => flattenHit(hit, indexPattern)) as Array< Record<string, unknown> > as ElasticSearchHit[]; @@ -83,7 +83,7 @@ function getCompProps(): DiscoverSidebarResponsiveProps { ]; for (const hit of hits) { - for (const key of Object.keys(indexPattern.flattenHit(hit))) { + for (const key of Object.keys(flattenHit(hit, indexPattern))) { mockfieldCounts[key] = (mockfieldCounts[key] || 0) + 1; } } diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js b/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js index 8f86cdad82cf7..be7e9c616273d 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js @@ -8,12 +8,12 @@ import { map, sortBy, without, each, defaults, isObject } from 'lodash'; import { i18n } from '@kbn/i18n'; +import { flattenHit } from '../../../../../../../../data/common'; function getFieldValues(hits, field, indexPattern) { const name = field.name; - const flattenHit = indexPattern.flattenHit; return map(hits, function (hit) { - return flattenHit(hit)[name]; + return flattenHit(hit, indexPattern)[name]; }); } diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts b/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts index c3ff7970c5aac..d4bc41f36b2d4 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts @@ -13,6 +13,7 @@ import { keys, each, cloneDeep, clone, uniq, filter, map } from 'lodash'; import realHits from '../../../../../../__fixtures__/real_hits.js'; import { IndexPattern } from '../../../../../../../../data/public'; +import { flattenHit } from '../../../../../../../../data/common'; // @ts-expect-error import { fieldCalculator } from './field_calculator'; @@ -120,7 +121,7 @@ describe('fieldCalculator', function () { let hits: any; beforeEach(function () { - hits = each(cloneDeep(realHits), (hit) => indexPattern.flattenHit(hit)); + hits = each(cloneDeep(realHits), (hit) => flattenHit(hit, indexPattern)); }); it('Should return an array of values for _source fields', function () { diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx b/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx index c68b1ab7b844c..18766b5df7f33 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx +++ b/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { SavedObjectSaveModal, showSaveModal } from '../../../../../../../saved_objects/public'; -import { SavedSearch } from '../../../../../saved_searches'; +import { SavedSearch, SaveSavedSearchOptions } from '../../../../../saved_searches'; import { IndexPattern } from '../../../../../../../data/common'; import { DiscoverServices } from '../../../../../build_services'; import { GetStateReturn } from '../../services/discover_state'; @@ -27,11 +27,7 @@ async function saveDataSource({ indexPattern: IndexPattern; navigateTo: (url: string) => void; savedSearch: SavedSearch; - saveOptions: { - confirmOverwrite: boolean; - isTitleDuplicateConfirmed: boolean; - onTitleDuplicate: () => void; - }; + saveOptions: SaveSavedSearchOptions; services: DiscoverServices; state: GetStateReturn; }) { @@ -47,14 +43,20 @@ async function saveDataSource({ }), 'data-test-subj': 'saveSearchSuccess', }); - - if (savedSearch.id !== prevSavedSearchId) { - navigateTo(`/view/${encodeURIComponent(savedSearch.id)}`); + if (id !== prevSavedSearchId) { + navigateTo(`/view/${encodeURIComponent(id)}`); } else { // Update defaults so that "reload saved query" functions correctly state.resetAppState(); - services.chrome.docTitle.change(savedSearch.lastSavedTitle!); - setBreadcrumbsTitle(savedSearch, services.chrome); + services.chrome.docTitle.change(savedSearch.title!); + + setBreadcrumbsTitle( + { + ...savedSearch, + id: prevSavedSearchId ?? id, + }, + services.chrome + ); } } } @@ -106,11 +108,10 @@ export async function onSaveSearch({ }) => { const currentTitle = savedSearch.title; savedSearch.title = newTitle; - savedSearch.copyOnSave = newCopyOnSave; - const saveOptions = { - confirmOverwrite: false, - isTitleDuplicateConfirmed, + const saveOptions: SaveSavedSearchOptions = { onTitleDuplicate, + copyOnSave: newCopyOnSave, + isTitleDuplicateConfirmed, }; const response = await saveDataSource({ indexPattern, @@ -133,7 +134,7 @@ export async function onSaveSearch({ <SavedObjectSaveModal onSave={onSave} onClose={() => {}} - title={savedSearch.title} + title={savedSearch.title ?? ''} showCopyOnSave={!!savedSearch.id} objectType={i18n.translate('discover.localMenu.saveSaveSearchObjectType', { defaultMessage: 'search', diff --git a/src/plugins/discover/public/application/apps/main/discover_main_route.tsx b/src/plugins/discover/public/application/apps/main/discover_main_route.tsx index a95668642558c..b674bfd6568ac 100644 --- a/src/plugins/discover/public/application/apps/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/apps/main/discover_main_route.tsx @@ -8,15 +8,18 @@ import React, { useEffect, useState, memo } from 'react'; import { History } from 'history'; import { useParams } from 'react-router-dom'; -import type { SavedObject as SavedObjectDeprecated } from 'src/plugins/saved_objects/public'; -import { IndexPatternAttributes, SavedObject } from 'src/plugins/data/common'; +import { i18n } from '@kbn/i18n'; +import { EuiEmptyPrompt } from '@elastic/eui'; + +import { IndexPatternAttributes, ISearchSource, SavedObject } from 'src/plugins/data/common'; import { DiscoverServices } from '../../../build_services'; -import { SavedSearch } from '../../../saved_searches'; +import { SavedSearch, getSavedSearch, getSavedSearchFullPathUrl } from '../../../saved_searches'; import { getState } from './services/discover_state'; import { loadIndexPattern, resolveIndexPattern } from './utils/resolve_index_pattern'; import { DiscoverMainApp } from './discover_main_app'; import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../../helpers/breadcrumbs'; import { redirectWhenMissing } from '../../../../../kibana_utils/public'; +import { DataViewSavedObjectConflictError } from '../../../../../data_views/common'; import { getUrlTracker } from '../../../kibana_services'; import { LoadingIndicator } from '../../components/common/loading_indicator'; @@ -37,6 +40,21 @@ interface DiscoverLandingParams { id: string; } +const DiscoverError = ({ error }: { error: Error }) => ( + <EuiEmptyPrompt + iconType="alert" + iconColor="danger" + title={ + <h2> + {i18n.translate('discover.discoverError.title', { + defaultMessage: 'Error loading Discover', + })} + </h2> + } + body={<p>{error.message}</p>} + /> +); + export function DiscoverMainRoute({ services, history }: DiscoverMainProps) { const { core, @@ -46,7 +64,7 @@ export function DiscoverMainRoute({ services, history }: DiscoverMainProps) { toastNotifications, http: { basePath }, } = services; - + const [error, setError] = useState<Error>(); const [savedSearch, setSavedSearch] = useState<SavedSearch>(); const indexPattern = savedSearch?.searchSource?.getField('index'); const [indexPatternList, setIndexPatternList] = useState< @@ -58,58 +76,76 @@ export function DiscoverMainRoute({ services, history }: DiscoverMainProps) { useEffect(() => { const savedSearchId = id; - async function loadDefaultOrCurrentIndexPattern(usedSavedSearch: SavedSearch) { - await data.indexPatterns.ensureDefaultDataView(); - const { appStateContainer } = getState({ history, uiSettings: config }); - const { index } = appStateContainer.getState(); - const ip = await loadIndexPattern(index || '', data.indexPatterns, config); - const ipList = ip.list as Array<SavedObject<IndexPatternAttributes>>; - const indexPatternData = await resolveIndexPattern( - ip, - usedSavedSearch.searchSource, - toastNotifications - ); - setIndexPatternList(ipList); - return indexPatternData; + async function loadDefaultOrCurrentIndexPattern(searchSource: ISearchSource) { + try { + await data.indexPatterns.ensureDefaultDataView(); + const { appStateContainer } = getState({ history, uiSettings: config }); + const { index } = appStateContainer.getState(); + const ip = await loadIndexPattern(index || '', data.indexPatterns, config); + + const ipList = ip.list as Array<SavedObject<IndexPatternAttributes>>; + const indexPatternData = await resolveIndexPattern(ip, searchSource, toastNotifications); + + setIndexPatternList(ipList); + + return indexPatternData; + } catch (e) { + setError(e); + } } async function loadSavedSearch() { try { - const loadedSavedSearch = await services.getSavedSearchById(savedSearchId); - const loadedIndexPattern = await loadDefaultOrCurrentIndexPattern(loadedSavedSearch); - if (loadedSavedSearch && !loadedSavedSearch?.searchSource.getField('index')) { - loadedSavedSearch.searchSource.setField('index', loadedIndexPattern); + const currentSavedSearch = await getSavedSearch(savedSearchId, { + search: services.data.search, + savedObjectsClient: core.savedObjects.client, + spaces: services.spaces, + }); + + const loadedIndexPattern = await loadDefaultOrCurrentIndexPattern( + currentSavedSearch.searchSource + ); + + if (!currentSavedSearch.searchSource.getField('index')) { + currentSavedSearch.searchSource.setField('index', loadedIndexPattern); } - setSavedSearch(loadedSavedSearch); - if (savedSearchId) { + + setSavedSearch(currentSavedSearch); + + if (currentSavedSearch.id) { chrome.recentlyAccessed.add( - (loadedSavedSearch as unknown as SavedObjectDeprecated).getFullPath(), - loadedSavedSearch.title, - loadedSavedSearch.id + getSavedSearchFullPathUrl(currentSavedSearch.id), + currentSavedSearch.title ?? '', + currentSavedSearch.id ); } } catch (e) { - redirectWhenMissing({ - history, - navigateToApp: core.application.navigateToApp, - basePath, - mapping: { - search: '/', - 'index-pattern': { - app: 'management', - path: `kibana/objects/savedSearches/${id}`, + if (e instanceof DataViewSavedObjectConflictError) { + setError(e); + } else { + redirectWhenMissing({ + history, + navigateToApp: core.application.navigateToApp, + basePath, + mapping: { + search: '/', + 'index-pattern': { + app: 'management', + path: `kibana/objects/savedSearches/${id}`, + }, }, - }, - toastNotifications, - onBeforeRedirect() { - getUrlTracker().setTrackedUrl('/'); - }, - })(e); + toastNotifications, + onBeforeRedirect() { + getUrlTracker().setTrackedUrl('/'); + }, + })(e); + } } } loadSavedSearch(); }, [ + core.savedObjects.client, basePath, chrome.recentlyAccessed, config, @@ -129,6 +165,10 @@ export function DiscoverMainRoute({ services, history }: DiscoverMainProps) { ); }, [chrome, savedSearch]); + if (error) { + return <DiscoverError error={error} />; + } + if (!indexPattern || !savedSearch) { return <LoadingIndicator />; } diff --git a/src/plugins/discover/public/application/apps/main/services/discover_state.test.ts b/src/plugins/discover/public/application/apps/main/services/discover_state.test.ts index 905d81a6fc716..9968ca6f1f63f 100644 --- a/src/plugins/discover/public/application/apps/main/services/discover_state.test.ts +++ b/src/plugins/discover/public/application/apps/main/services/discover_state.test.ts @@ -14,7 +14,7 @@ import { } from './discover_state'; import { createBrowserHistory, History } from 'history'; import { dataPluginMock } from '../../../../../../data/public/mocks'; -import { SavedSearch } from '../../../../saved_searches'; +import type { SavedSearch } from '../../../../saved_searches'; import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common'; let history: History; diff --git a/src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts b/src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts index 28f5f96acc144..c719f83980aa0 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts +++ b/src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts @@ -15,6 +15,20 @@ import { indexPatternMock } from '../../../../__mocks__/index_pattern'; import { SearchSource } from '../../../../../../data/common'; describe('test useDiscoverState', () => { + const originalSavedObjectsClient = discoverServiceMock.core.savedObjects.client; + + beforeAll(() => { + discoverServiceMock.core.savedObjects.client.resolve = jest.fn().mockReturnValue({ + saved_object: { + attributes: {}, + }, + }); + }); + + afterAll(() => { + discoverServiceMock.core.savedObjects.client = originalSavedObjectsClient; + }); + test('return is valid', async () => { const { history } = createSearchSessionMock(); diff --git a/src/plugins/discover/public/application/apps/main/services/use_discover_state.ts b/src/plugins/discover/public/application/apps/main/services/use_discover_state.ts index 223d896b16cd1..ce30c0749b938 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_discover_state.ts +++ b/src/plugins/discover/public/application/apps/main/services/use_discover_state.ts @@ -11,7 +11,7 @@ import { History } from 'history'; import { getState } from './discover_state'; import { getStateDefaults } from '../utils/get_state_defaults'; import { DiscoverServices } from '../../../../build_services'; -import { SavedSearch } from '../../../../saved_searches'; +import { SavedSearch, getSavedSearch } from '../../../../saved_searches'; import { loadIndexPattern } from '../utils/resolve_index_pattern'; import { useSavedSearch as useSavedSearchData } from './use_saved_search'; import { @@ -148,7 +148,12 @@ export function useDiscoverState({ */ const resetSavedSearch = useCallback( async (id?: string) => { - const newSavedSearch = await services.getSavedSearchById(id); + const newSavedSearch = await getSavedSearch(id, { + search: services.data.search, + savedObjectsClient: services.core.savedObjects.client, + spaces: services.spaces, + }); + const newIndexPattern = newSavedSearch.searchSource.getField('index') || indexPattern; newSavedSearch.searchSource.setField('index', newIndexPattern); const newAppState = getStateDefaults({ diff --git a/src/plugins/discover/public/application/apps/main/services/use_saved_search.ts b/src/plugins/discover/public/application/apps/main/services/use_saved_search.ts index d11c76283fedd..6cadfbb89acfb 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_saved_search.ts +++ b/src/plugins/discover/public/application/apps/main/services/use_saved_search.ts @@ -9,7 +9,7 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; import { BehaviorSubject, Subject } from 'rxjs'; import { DiscoverServices } from '../../../../build_services'; import { DiscoverSearchSessionManager } from './discover_search_session'; -import { SearchSource } from '../../../../../../data/common'; +import { ISearchSource } from '../../../../../../data/common'; import { GetStateReturn } from './discover_state'; import { ElasticSearchHit } from '../../../doc_views/doc_views_types'; import { RequestAdapter } from '../../../../../../inspector/public'; @@ -91,7 +91,7 @@ export const useSavedSearch = ({ }: { initialFetchStatus: FetchStatus; searchSessionManager: DiscoverSearchSessionManager; - searchSource: SearchSource; + searchSource: ISearchSource; services: DiscoverServices; stateContainer: GetStateReturn; useNewFieldsApi: boolean; diff --git a/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts b/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts index 1ce7023539be4..211c4e5c8b069 100644 --- a/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts +++ b/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { IndexPattern } from 'src/plugins/data/common'; +import { flattenHit, IndexPattern } from '../../../../../../data/common'; import { ElasticSearchHit } from '../../../doc_views/doc_views_types'; /** @@ -22,7 +22,7 @@ export function calcFieldCounts( return {}; } for (const hit of rows) { - const fields = Object.keys(indexPattern.flattenHit(hit)); + const fields = Object.keys(flattenHit(hit, indexPattern)); for (const fieldName of fields) { counts[fieldName] = (counts[fieldName] || 0) + 1; } diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_all.ts b/src/plugins/discover/public/application/apps/main/utils/fetch_all.ts index 53d13ee547b0f..e9d9335abcda0 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_all.ts +++ b/src/plugins/discover/public/application/apps/main/utils/fetch_all.ts @@ -14,11 +14,11 @@ import { sendResetMsg, } from '../services/use_saved_search_messages'; import { updateSearchSource } from './update_search_source'; -import { SortOrder } from '../../../../saved_searches/types'; +import type { SortOrder } from '../../../../saved_searches'; import { fetchDocuments } from './fetch_documents'; import { fetchTotalHits } from './fetch_total_hits'; import { fetchChart } from './fetch_chart'; -import { SearchSource } from '../../../../../../data/common'; +import { ISearchSource } from '../../../../../../data/common'; import { Adapters } from '../../../../../../inspector'; import { AppState } from '../services/discover_state'; import { FetchStatus } from '../../../types'; @@ -29,7 +29,7 @@ import { ReduxLikeStateContainer } from '../../../../../../kibana_utils/common'; export function fetchAll( dataSubjects: SavedSearchData, - searchSource: SearchSource, + searchSource: ISearchSource, reset = false, fetchDeps: { abortController: AbortController; diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts b/src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts index 67f34c7503c59..50f3a1b8bfea7 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts +++ b/src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts @@ -11,7 +11,7 @@ import { DataPublicPluginStart, isCompleteResponse, search, - SearchSource, + ISearchSource, } from '../../../../../../data/public'; import { Adapters } from '../../../../../../inspector'; import { getChartAggConfigs, getDimensions } from './index'; @@ -25,7 +25,7 @@ import { sendErrorMsg, sendLoadingMsg } from '../services/use_saved_search_messa export function fetchChart( data$: SavedSearchData, - searchSource: SearchSource, + searchSource: ISearchSource, { abortController, appStateContainer, @@ -114,7 +114,7 @@ export function fetchChart( } export function updateSearchSource( - searchSource: SearchSource, + searchSource: ISearchSource, interval: string, data: DataPublicPluginStart ) { diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts b/src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts index 2f06a9dbbb3db..6c5eff7cff702 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts +++ b/src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { filter } from 'rxjs/operators'; import { Adapters } from '../../../../../../inspector/common'; -import { isCompleteResponse, SearchSource } from '../../../../../../data/common'; +import { isCompleteResponse, ISearchSource } from '../../../../../../data/common'; import { FetchStatus } from '../../../types'; import { SavedSearchData } from '../services/use_saved_search'; import { sendErrorMsg, sendLoadingMsg } from '../services/use_saved_search_messages'; @@ -17,7 +17,7 @@ import { DiscoverServices } from '../../../../build_services'; export const fetchDocuments = ( data$: SavedSearchData, - searchSource: SearchSource, + searchSource: ISearchSource, { abortController, inspectorAdapters, diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts b/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts index 9688f5ddd614d..cfab0d17fcd54 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts +++ b/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts @@ -11,7 +11,7 @@ import { filter } from 'rxjs/operators'; import { DataPublicPluginStart, isCompleteResponse, - SearchSource, + ISearchSource, } from '../../../../../../data/public'; import { Adapters } from '../../../../../../inspector/common'; import { FetchStatus } from '../../../types'; @@ -20,7 +20,7 @@ import { sendErrorMsg, sendLoadingMsg } from '../services/use_saved_search_messa export function fetchTotalHits( data$: SavedSearchData, - searchSource: SearchSource, + searchSource: ISearchSource, { abortController, data, diff --git a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts b/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts index 3eef49fe6ddcb..515565f0062c9 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; -import { SearchSource } from '../../../../../../data/public'; +import { ISearchSource } from '../../../../../../data/public'; import { dataPluginMock } from '../../../../../../data/public/mocks'; import { getChartAggConfigs } from './get_chart_agg_configs'; @@ -22,7 +22,7 @@ describe('getChartAggConfigs', () => { } }, removeField: jest.fn(), - } as unknown as SearchSource; + } as unknown as ISearchSource; const dataMock = dataPluginMock.createStartContract(); diff --git a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts b/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts index 2665254027fd9..65f98f72beec0 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { SearchSource } from '../../../../../../data/common'; +import { ISearchSource } from '../../../../../../data/common'; import { DataPublicPluginStart } from '../../../../../../data/public'; /** @@ -13,7 +13,7 @@ import { DataPublicPluginStart } from '../../../../../../data/public'; * for Discover's histogram vis */ export function getChartAggConfigs( - searchSource: SearchSource, + searchSource: ISearchSource, histogramInterval: string, data: DataPublicPluginStart ) { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts b/src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts index b98662f2db3b5..35a6e955fe5b2 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts @@ -9,7 +9,7 @@ import { dataPluginMock } from '../../../../../../data/public/mocks'; import { getDimensions } from './get_dimensions'; import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; -import { SearchSource, calculateBounds } from '../../../../../../data/common'; +import { ISearchSource, calculateBounds } from '../../../../../../data/common'; import { getChartAggConfigs } from './get_chart_agg_configs'; test('getDimensions', () => { @@ -23,7 +23,7 @@ test('getDimensions', () => { return indexPattern; } }, - } as unknown as SearchSource; + } as unknown as ISearchSource; const dataMock = dataPluginMock.createStartContract(); dataMock.query.timefilter.timefilter.getTime = () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts b/src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts index 528f0e74d3ed6..de79a9425f17c 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts @@ -12,7 +12,7 @@ import { FetchStatus } from '../../../types'; import type { AutoRefreshDoneFn, DataPublicPluginStart, - SearchSource, + ISearchSource, } from '../../../../../../data/public'; import { DataMain$, DataRefetch$ } from '../services/use_saved_search'; import { DiscoverSearchSessionManager } from '../services/discover_search_session'; @@ -33,7 +33,7 @@ export function getFetch$({ main$: DataMain$; refetch$: DataRefetch$; searchSessionManager: DiscoverSearchSessionManager; - searchSource: SearchSource; + searchSource: ISearchSource; initialFetchStatus: FetchStatus; }) { const { timefilter } = data.query.timefilter; diff --git a/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts b/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts index 21292fabdd13f..437d4fda666fc 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts @@ -11,7 +11,7 @@ import type { IUiSettingsClient } from 'src/core/public'; import type { DataPublicPluginStart } from 'src/plugins/data/public'; import type { ISearchSource, SearchSourceFields } from 'src/plugins/data/common'; import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; -import type { SavedSearch, SortOrder } from '../../../../saved_searches/types'; +import type { SavedSearch, SortOrder } from '../../../../saved_searches'; import { getSortForSearchSource } from '../components/doc_table'; import { AppState } from '../services/discover_state'; diff --git a/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts b/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts index cd23d52022374..f2f6e4a002aaf 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts @@ -6,9 +6,13 @@ * Side Public License, v 1. */ -import { cloneDeep } from 'lodash'; +import { cloneDeep, isEqual } from 'lodash'; import { IUiSettingsClient } from 'kibana/public'; -import { DEFAULT_COLUMNS_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; +import { + DEFAULT_COLUMNS_SETTING, + SEARCH_FIELDS_FROM_SOURCE, + SORT_DEFAULT_ORDER_SETTING, +} from '../../../../../common'; import { SavedSearch } from '../../../../saved_searches'; import { DataPublicPluginStart } from '../../../../../../data/public'; @@ -19,6 +23,9 @@ function getDefaultColumns(savedSearch: SavedSearch, config: IUiSettingsClient) if (savedSearch.columns && savedSearch.columns.length > 0) { return [...savedSearch.columns]; } + if (config.get(SEARCH_FIELDS_FROM_SOURCE) && isEqual(config.get(DEFAULT_COLUMNS_SETTING), [])) { + return ['_source']; + } return [...config.get(DEFAULT_COLUMNS_SETTING)]; } @@ -31,10 +38,11 @@ export function getStateDefaults({ data: DataPublicPluginStart; savedSearch: SavedSearch; }) { - const searchSource = savedSearch.searchSource; - const indexPattern = savedSearch.searchSource.getField('index'); + const { searchSource } = savedSearch; + const indexPattern = searchSource.getField('index'); + const query = searchSource.getField('query') || data.query.queryString.getDefaultQuery(); - const sort = getSortArray(savedSearch.sort, indexPattern!); + const sort = getSortArray(savedSearch.sort ?? [], indexPattern!); const columns = getDefaultColumns(savedSearch, config); const defaultState = { @@ -43,7 +51,7 @@ export function getStateDefaults({ ? getDefaultSort(indexPattern, config.get(SORT_DEFAULT_ORDER_SETTING, 'desc')) : sort, columns, - index: indexPattern!.id, + index: indexPattern?.id, interval: 'auto', filters: cloneDeep(searchSource.getOwnField('filter')), hideChart: undefined, diff --git a/src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts b/src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts index a5e1e2bb6c2ea..584fbe14cb59e 100644 --- a/src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts +++ b/src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts @@ -10,9 +10,10 @@ import { updateSearchSource } from './update_search_source'; import { IndexPattern } from '../../../../../../data/public'; import { SavedSearch } from '../../../../saved_searches'; import { AppState } from '../services/discover_state'; -import { SortOrder } from '../../../../saved_searches/types'; +import type { SortOrder } from '../../../../saved_searches'; import { SavedObjectSaveOpts } from '../../../../../../saved_objects/public'; import { DiscoverServices } from '../../../../build_services'; +import { saveSavedSearch } from '../../../../saved_searches'; /** * Helper function to update and persist the given savedSearch @@ -52,8 +53,10 @@ export async function persistSavedSearch( } try { - const id = await savedSearch.save(saveOptions); - onSuccess(id); + const id = await saveSavedSearch(savedSearch, saveOptions, services.core.savedObjects.client); + if (id) { + onSuccess(id); + } return { id }; } catch (saveError) { onError(saveError, savedSearch); diff --git a/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts b/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts index d30b67db31186..613615446ee08 100644 --- a/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts +++ b/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts @@ -7,7 +7,7 @@ */ import { i18n } from '@kbn/i18n'; -import type { IndexPattern, IndexPatternsContract, SearchSource } from 'src/plugins/data/common'; +import type { IndexPattern, IndexPatternsContract, ISearchSource } from 'src/plugins/data/common'; import type { IUiSettingsClient, SavedObject, ToastsStart } from 'kibana/public'; export type IndexPatternSavedObject = SavedObject & { title: string }; @@ -95,7 +95,7 @@ export async function loadIndexPattern( */ export function resolveIndexPattern( ip: IndexPatternData, - searchSource: SearchSource, + searchSource: ISearchSource, toastNotifications: ToastsStart ) { const { loaded: loadedIndexPattern, stateVal, stateValFound } = ip; diff --git a/src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts b/src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts index 945140e0586ab..22f3b6ad86f6c 100644 --- a/src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts +++ b/src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts @@ -9,7 +9,7 @@ import { updateSearchSource } from './update_search_source'; import { createSearchSourceMock } from '../../../../../../data/common/search/search_source/mocks'; import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { SortOrder } from '../../../../saved_searches/types'; +import type { SortOrder } from '../../../../saved_searches'; import { discoverServiceMock } from '../../../../__mocks__/services'; describe('updateSearchSource', () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/update_search_source.ts b/src/plugins/discover/public/application/apps/main/utils/update_search_source.ts index 4dfcbc7b79712..6d592e176afe5 100644 --- a/src/plugins/discover/public/application/apps/main/utils/update_search_source.ts +++ b/src/plugins/discover/public/application/apps/main/utils/update_search_source.ts @@ -8,7 +8,7 @@ import { SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; import { IndexPattern, ISearchSource } from '../../../../../../data/common'; -import { SortOrder } from '../../../../saved_searches/types'; +import type { SortOrder } from '../../../../saved_searches'; import { DiscoverServices } from '../../../../build_services'; import { getSortForSearchSource } from '../components/doc_table'; diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx index 0fe506b3b8537..11323080274a9 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx @@ -21,7 +21,7 @@ import { EuiLoadingSpinner, EuiIcon, } from '@elastic/eui'; -import type { IndexPattern } from 'src/plugins/data/common'; +import { flattenHit, IndexPattern } from '../../../../../data/common'; import { DocViewFilterFn, ElasticSearchHit } from '../../doc_views/doc_views_types'; import { getSchemaDetectors } from './discover_grid_schema'; import { DiscoverGridFlyout } from './discover_grid_flyout'; @@ -271,7 +271,7 @@ export const DiscoverGrid = ({ getRenderCellValueFn( indexPattern, displayedRows, - displayedRows ? displayedRows.map((hit) => indexPattern.flattenHit(hit)) : [], + displayedRows ? displayedRows.map((hit) => flattenHit(hit, indexPattern)) : [], useNewFieldsApi, fieldsToShow, services.uiSettings.get(MAX_DOC_FIELDS_DISPLAYED) diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx index b1823eb3d668c..a31b551821ddb 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx @@ -9,7 +9,7 @@ import React, { useContext } from 'react'; import { EuiDataGridColumnCellActionProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IndexPatternField } from '../../../../../data/common'; +import { flattenHit, IndexPatternField } from '../../../../../data/common'; import { DiscoverGridContext } from './discover_grid_context'; export const FilterInBtn = ({ @@ -27,7 +27,7 @@ export const FilterInBtn = ({ <Component onClick={() => { const row = context.rows[rowIndex]; - const flattened = context.indexPattern.flattenHit(row); + const flattened = flattenHit(row, context.indexPattern); if (flattened) { context.onFilter(columnId, flattened[columnId], '+'); @@ -60,7 +60,7 @@ export const FilterOutBtn = ({ <Component onClick={() => { const row = context.rows[rowIndex]; - const flattened = context.indexPattern.flattenHit(row); + const flattened = flattenHit(row, context.indexPattern); if (flattened) { context.onFilter(columnId, flattened[columnId], '-'); diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx index 41cf3f5a68edb..e9b93e21553a2 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx @@ -17,6 +17,17 @@ import { esHits } from '../../../__mocks__/es_hits'; import { indexPatternMock } from '../../../__mocks__/index_pattern'; import { DiscoverGridContext } from './discover_grid_context'; +const baseContextMock = { + expanded: undefined, + setExpanded: jest.fn(), + rows: esHits, + onFilter: jest.fn(), + indexPattern: indexPatternMock, + isDarkMode: false, + selectedDocs: [], + setSelectedDocs: jest.fn(), +}; + describe('document selection', () => { describe('getDocId', () => { test('doc with custom routing', () => { @@ -39,14 +50,7 @@ describe('document selection', () => { describe('SelectButton', () => { test('is not checked', () => { const contextMock = { - expanded: undefined, - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, - selectedDocs: [], - setSelectedDocs: jest.fn(), + ...baseContextMock, }; const component = mountWithIntl( @@ -68,14 +72,8 @@ describe('document selection', () => { test('is checked', () => { const contextMock = { - expanded: undefined, - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, + ...baseContextMock, selectedDocs: ['i::1::'], - setSelectedDocs: jest.fn(), }; const component = mountWithIntl( @@ -97,14 +95,7 @@ describe('document selection', () => { test('adding a selection', () => { const contextMock = { - expanded: undefined, - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, - selectedDocs: [], - setSelectedDocs: jest.fn(), + ...baseContextMock, }; const component = mountWithIntl( @@ -126,14 +117,8 @@ describe('document selection', () => { }); test('removing a selection', () => { const contextMock = { - expanded: undefined, - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, + ...baseContextMock, selectedDocs: ['i::1::'], - setSelectedDocs: jest.fn(), }; const component = mountWithIntl( diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx index d1299b39a25b2..3f7cb70091cfa 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx @@ -14,17 +14,21 @@ import { DiscoverGridContext } from './discover_grid_context'; import { indexPatternMock } from '../../../__mocks__/index_pattern'; import { esHits } from '../../../__mocks__/es_hits'; +const baseContextMock = { + expanded: undefined, + setExpanded: jest.fn(), + rows: esHits, + onFilter: jest.fn(), + indexPattern: indexPatternMock, + isDarkMode: false, + selectedDocs: [], + setSelectedDocs: jest.fn(), +}; + describe('Discover grid view button ', function () { it('when no document is expanded, setExpanded is called with current document', async () => { const contextMock = { - expanded: undefined, - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, - selectedDocs: [], - setSelectedDocs: jest.fn(), + ...baseContextMock, }; const component = mountWithIntl( @@ -45,14 +49,8 @@ describe('Discover grid view button ', function () { }); it('when the current document is expanded, setExpanded is called with undefined', async () => { const contextMock = { + ...baseContextMock, expanded: esHits[0], - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, - selectedDocs: [], - setSelectedDocs: jest.fn(), }; const component = mountWithIntl( @@ -73,14 +71,8 @@ describe('Discover grid view button ', function () { }); it('when another document is expanded, setExpanded is called with the current document', async () => { const contextMock = { + ...baseContextMock, expanded: esHits[0], - setExpanded: jest.fn(), - rows: esHits, - onFilter: jest.fn(), - indexPattern: indexPatternMock, - isDarkMode: false, - selectedDocs: [], - setSelectedDocs: jest.fn(), }; const component = mountWithIntl( diff --git a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx index 5aca237d46581..6556876217953 100644 --- a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx @@ -11,6 +11,7 @@ import { ReactWrapper, shallow } from 'enzyme'; import { getRenderCellValueFn } from './get_render_cell_value'; import { indexPatternMock } from '../../../__mocks__/index_pattern'; import { ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { flattenHit } from 'src/plugins/data/common'; jest.mock('../../../../../kibana_react/public', () => ({ useUiSetting: () => true, @@ -68,12 +69,16 @@ const rowsFieldsWithTopLevelObject: ElasticSearchHit[] = [ }, ]; +const flatten = (hit: ElasticSearchHit): Record<string, unknown> => { + return flattenHit(hit, indexPatternMock); +}; + describe('Discover grid cell rendering', function () { it('renders bytes column correctly', () => { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsSource, - rowsSource.map((row) => indexPatternMock.flattenHit(row)), + rowsSource.map(flatten), false, [], 100 @@ -95,7 +100,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsSource, - rowsSource.map((row) => indexPatternMock.flattenHit(row)), + rowsSource.map(flatten), false, [], 100 @@ -146,7 +151,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsSource, - rowsSource.map((row) => indexPatternMock.flattenHit(row)), + rowsSource.map(flatten), false, [], 100 @@ -189,7 +194,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFields, - rowsFields.map((row) => indexPatternMock.flattenHit(row)), + rowsFields.map(flatten), true, [], 100 @@ -244,7 +249,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFields, - rowsFields.map((row) => indexPatternMock.flattenHit(row)), + rowsFields.map(flatten), true, [], // this is the number of rendered items @@ -287,7 +292,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFields, - rowsFields.map((row) => indexPatternMock.flattenHit(row)), + rowsFields.map(flatten), true, [], 100 @@ -335,7 +340,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFieldsWithTopLevelObject, - rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)), + rowsFieldsWithTopLevelObject.map(flatten), true, [], 100 @@ -376,7 +381,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFieldsWithTopLevelObject, - rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)), + rowsFieldsWithTopLevelObject.map(flatten), true, [], 100 @@ -416,7 +421,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFieldsWithTopLevelObject, - rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)), + rowsFieldsWithTopLevelObject.map(flatten), true, [], 100 @@ -447,7 +452,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsFieldsWithTopLevelObject, - rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)), + rowsFieldsWithTopLevelObject.map(flatten), true, [], 100 @@ -466,7 +471,9 @@ describe('Discover grid cell rendering', function () { <span dangerouslySetInnerHTML={ Object { - "__html": 100, + "__html": Array [ + 100, + ], } } /> @@ -477,7 +484,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsSource, - rowsSource.map((row) => indexPatternMock.flattenHit(row)), + rowsSource.map(flatten), false, [], 100 @@ -499,7 +506,7 @@ describe('Discover grid cell rendering', function () { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, rowsSource, - rowsSource.map((row) => indexPatternMock.flattenHit(row)), + rowsSource.map(flatten), false, [], 100 diff --git a/src/plugins/discover/public/application/components/table/table.test.tsx b/src/plugins/discover/public/application/components/table/table.test.tsx index 3f010d9d07737..ce914edcec703 100644 --- a/src/plugins/discover/public/application/components/table/table.test.tsx +++ b/src/plugins/discover/public/application/components/table/table.test.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { findTestSubject } from '@elastic/eui/lib/test'; import { DocViewerTable, DocViewerTableProps } from './table'; -import { indexPatterns, IndexPattern } from '../../../../../data/public'; +import { IndexPattern } from '../../../../../data/public'; import { ElasticSearchHit } from '../../doc_views/doc_views_types'; jest.mock('../../../kibana_services', () => ({ @@ -65,7 +65,7 @@ const indexPattern = { ], }, metaFields: ['_index', '_score'], - flattenHit: undefined, + flattenHit: jest.fn(), formatHit: jest.fn((hit) => hit._source), } as unknown as IndexPattern; @@ -73,8 +73,6 @@ indexPattern.fields.getByName = (name: string) => { return indexPattern.fields.getAll().find((field) => field.name === name); }; -indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields); - const mountComponent = (props: DocViewerTableProps) => { return mountWithIntl(<DocViewerTable {...props} />); }; diff --git a/src/plugins/discover/public/application/components/table/table.tsx b/src/plugins/discover/public/application/components/table/table.tsx index eab3ba6e3d29a..7f597d846f88f 100644 --- a/src/plugins/discover/public/application/components/table/table.tsx +++ b/src/plugins/discover/public/application/components/table/table.tsx @@ -9,6 +9,7 @@ import React, { useCallback, useMemo } from 'react'; import { EuiInMemoryTable } from '@elastic/eui'; import { IndexPattern, IndexPatternField } from '../../../../../data/public'; +import { flattenHit } from '../../../../../data/common'; import { SHOW_MULTIFIELDS } from '../../../../common'; import { getServices } from '../../../kibana_services'; import { isNestedFieldParent } from '../../apps/main/utils/nested_fields'; @@ -95,7 +96,7 @@ export const DocViewerTable = ({ return null; } - const flattened = indexPattern?.flattenHit(hit); + const flattened = flattenHit(hit, indexPattern, { source: true }); const fieldsToShow = getFieldsToShow(Object.keys(flattened), indexPattern, showMultiFields); const items: FieldRecord[] = Object.keys(flattened) diff --git a/src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts b/src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts index f3edc523f4464..f09131cb5c926 100644 --- a/src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts +++ b/src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts @@ -8,7 +8,7 @@ import { createSearchSourceMock } from '../../../../../data/common/search/search_source/mocks'; import { updateSearchSource } from './update_search_source'; import { indexPatternMock } from '../../../__mocks__/index_pattern'; -import { SortOrder } from '../../../saved_searches/types'; +import type { SortOrder } from '../../../saved_searches'; describe('updateSearchSource', () => { const defaults = { diff --git a/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx index ef8670f976672..8849806cf5959 100644 --- a/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx +++ b/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx @@ -165,7 +165,7 @@ export class SavedSearchEmbeddable const executionContext = { type: this.type, name: 'discover', - id: this.savedSearch.id, + id: this.savedSearch.id!, description: this.output.title || this.output.defaultTitle || '', url: this.output.editUrl, parent: this.input.executionContext, @@ -232,7 +232,7 @@ export class SavedSearchEmbeddable searchDescription: this.savedSearch.description, description: this.savedSearch.description, inspectorAdapters: this.inspectorAdapters, - searchTitle: this.savedSearch.lastSavedTitle, + searchTitle: this.savedSearch.title, services: this.services, onAddColumn: (columnName: string) => { if (!props.columns) { @@ -404,7 +404,6 @@ export class SavedSearchEmbeddable public destroy() { super.destroy(); - this.savedSearch.destroy(); if (this.searchProps) { delete this.searchProps; } diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts b/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts index 95f5b2d3ce284..a8b492d368768 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts +++ b/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts @@ -20,6 +20,11 @@ import { TimeRange } from '../../../../data/public'; import { SearchInput, SearchOutput } from './types'; import { SEARCH_EMBEDDABLE_TYPE } from './constants'; import { SavedSearchEmbeddable } from './saved_search_embeddable'; +import { + getSavedSearch, + getSavedSearchUrl, + throwErrorOnSavedSearchUrlConflict, +} from '../../saved_searches'; interface StartServices { executeTriggerActions: UiActionsStart['executeTriggerActions']; @@ -59,20 +64,27 @@ export class SearchEmbeddableFactory input: Partial<SearchInput> & { id: string; timeRange: TimeRange }, parent?: Container ): Promise<SavedSearchEmbeddable | ErrorEmbeddable> => { - const filterManager = getServices().filterManager; - - const url = await getServices().getSavedSearchUrlById(savedObjectId); - const editUrl = getServices().addBasePath(`/app/discover${url}`); + const services = getServices(); + const filterManager = services.filterManager; + const url = getSavedSearchUrl(savedObjectId); + const editUrl = services.addBasePath(`/app/discover${url}`); try { - const savedObject = await getServices().getSavedSearchById(savedObjectId); - const indexPattern = savedObject.searchSource.getField('index'); + const savedSearch = await getSavedSearch(savedObjectId, { + search: services.data.search, + savedObjectsClient: services.core.savedObjects.client, + spaces: services.spaces, + }); + + await throwErrorOnSavedSearchUrlConflict(savedSearch); + + const indexPattern = savedSearch.searchSource.getField('index'); const { executeTriggerActions } = await this.getStartServices(); const { SavedSearchEmbeddable: SavedSearchEmbeddableClass } = await import( './saved_search_embeddable' ); return new SavedSearchEmbeddableClass( { - savedSearch: savedObject, + savedSearch, editUrl, editPath: url, filterManager, diff --git a/src/plugins/discover/public/application/embeddable/types.ts b/src/plugins/discover/public/application/embeddable/types.ts index 5a08534918d4f..de109e3fa7879 100644 --- a/src/plugins/discover/public/application/embeddable/types.ts +++ b/src/plugins/discover/public/application/embeddable/types.ts @@ -13,7 +13,7 @@ import { IEmbeddable, } from 'src/plugins/embeddable/public'; import { Filter, IndexPattern, TimeRange, Query } from '../../../../data/public'; -import { SavedSearch } from '../..'; +import { SavedSearch } from '../../saved_searches'; import { SortOrder } from '../apps/main/components/doc_table/components/table_header/helpers'; export interface SearchInput extends EmbeddableInput { diff --git a/src/plugins/discover/public/application/embeddable/view_saved_search_action.ts b/src/plugins/discover/public/application/embeddable/view_saved_search_action.ts index 69c273f326c61..e4b97d011ff64 100644 --- a/src/plugins/discover/public/application/embeddable/view_saved_search_action.ts +++ b/src/plugins/discover/public/application/embeddable/view_saved_search_action.ts @@ -12,6 +12,7 @@ import { IEmbeddable, ViewMode } from '../../../../embeddable/public'; import { Action } from '../../../../ui_actions/public'; import { SavedSearchEmbeddable } from './saved_search_embeddable'; import { SEARCH_EMBEDDABLE_TYPE } from '../../../common'; +import { getSavedSearchUrl } from '../../saved_searches'; export const ACTION_VIEW_SAVED_SEARCH = 'ACTION_VIEW_SAVED_SEARCH'; @@ -28,7 +29,7 @@ export class ViewSavedSearchAction implements Action<ViewSearchContext> { async execute(context: ActionExecutionContext<ViewSearchContext>): Promise<void> { const { embeddable } = context; const savedSearchId = (embeddable as SavedSearchEmbeddable).getSavedSearch().id; - const path = `#/view/${encodeURIComponent(savedSearchId)}`; + const path = getSavedSearchUrl(savedSearchId); const app = embeddable ? embeddable.getOutput().editApp : undefined; await this.application.navigateToApp(app ? app : 'discover', { path }); } diff --git a/src/plugins/discover/public/application/helpers/state_helpers.ts b/src/plugins/discover/public/application/helpers/state_helpers.ts index fd17ec9516ab5..bb64f823d61a6 100644 --- a/src/plugins/discover/public/application/helpers/state_helpers.ts +++ b/src/plugins/discover/public/application/helpers/state_helpers.ts @@ -24,6 +24,7 @@ export function handleSourceColumnState<TState extends { columns?: string[] }>( } const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE); const defaultColumns = uiSettings.get(DEFAULT_COLUMNS_SETTING); + if (useNewFieldsApi) { // if fields API is used, filter out the source column let cleanedColumns = state.columns.filter((column) => column !== '_source'); @@ -39,9 +40,13 @@ export function handleSourceColumnState<TState extends { columns?: string[] }>( } else if (state.columns.length === 0) { // if _source fetching is used and there are no column, switch back to default columns // this can happen if the fields API was previously used + const columns = defaultColumns; + if (columns.length === 0) { + columns.push('_source'); + } return { ...state, - columns: [...defaultColumns], + columns: [...columns], }; } diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts index e88f00fadcbf1..ab2484abee892 100644 --- a/src/plugins/discover/public/build_services.ts +++ b/src/plugins/discover/public/build_services.ts @@ -31,13 +31,14 @@ import { UiCounterMetricType } from '@kbn/analytics'; import { Storage } from '../../kibana_utils/public'; import { DiscoverStartPlugins } from './plugin'; -import { createSavedSearchesLoader, SavedSearch } from './saved_searches'; import { getHistory } from './kibana_services'; import { KibanaLegacyStart } from '../../kibana_legacy/public'; import { UrlForwardingStart } from '../../url_forwarding/public'; import { NavigationPublicPluginStart } from '../../navigation/public'; import { IndexPatternFieldEditorStart } from '../../index_pattern_field_editor/public'; +import type { SpacesApi } from '../../../../x-pack/plugins/spaces/public'; + export interface DiscoverServices { addBasePath: (path: string) => string; capabilities: Capabilities; @@ -57,13 +58,12 @@ export interface DiscoverServices { urlForwarding: UrlForwardingStart; timefilter: TimefilterContract; toastNotifications: ToastsStart; - getSavedSearchById: (id?: string) => Promise<SavedSearch>; - getSavedSearchUrlById: (id: string) => Promise<string>; uiSettings: IUiSettingsClient; trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void; indexPatternFieldEditor: IndexPatternFieldEditorStart; http: HttpStart; storage: Storage; + spaces?: SpacesApi; } export function buildServices( @@ -71,11 +71,6 @@ export function buildServices( plugins: DiscoverStartPlugins, context: PluginInitializerContext ): DiscoverServices { - const services = { - savedObjectsClient: core.savedObjects.client, - savedObjects: plugins.savedObjects, - }; - const savedObjectService = createSavedSearchesLoader(services); const { usageCollection } = plugins; const storage = new Storage(localStorage); @@ -88,8 +83,6 @@ export function buildServices( docLinks: core.docLinks, theme: plugins.charts.theme, filterManager: plugins.data.query.filterManager, - getSavedSearchById: async (id?: string) => savedObjectService.get(id), - getSavedSearchUrlById: async (id: string) => savedObjectService.urlFor(id), history: getHistory, indexPatterns: plugins.data.indexPatterns, inspector: plugins.inspector, @@ -107,5 +100,6 @@ export function buildServices( trackUiMetric: usageCollection?.reportUiCounter.bind(usageCollection, 'discover'), indexPatternFieldEditor: plugins.indexPatternFieldEditor, http: core.http, + spaces: plugins.spaces, }; } diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index 3840df4353faf..f6cd687c962c3 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -9,12 +9,23 @@ import { PluginInitializerContext } from 'kibana/public'; import { DiscoverPlugin } from './plugin'; +export { + getSavedSearch, + getSavedSearchFullPathUrl, + getSavedSearchUrl, + getSavedSearchUrlConflictMessage, + throwErrorOnSavedSearchUrlConflict, + SavedSearch, + LegacySavedSearch, + SavedSearchLoader, + __LEGACY, +} from './saved_searches'; + export { DiscoverSetup, DiscoverStart } from './plugin'; export function plugin(initializerContext: PluginInitializerContext) { return new DiscoverPlugin(initializerContext); } -export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; export { loadSharingDataHelpers } from './shared'; diff --git a/src/plugins/discover/public/mocks.ts b/src/plugins/discover/public/mocks.ts index 71de630132b0a..6a3c703ea0da8 100644 --- a/src/plugins/discover/public/mocks.ts +++ b/src/plugins/discover/public/mocks.ts @@ -24,7 +24,9 @@ const createSetupContract = (): Setup => { const createStartContract = (): Start => { const startContract: Start = { - savedSearchLoader: {} as DiscoverStart['savedSearchLoader'], + __LEGACY: { + savedSearchLoader: {} as DiscoverStart['__LEGACY']['savedSearchLoader'], + }, urlGenerator: { createUrl: jest.fn(), } as unknown as DiscoverStart['urlGenerator'], diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index afb83d6cbd667..e34e7644caa25 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -45,7 +45,7 @@ import { getScopedHistory, syncHistoryLocations, } from './kibana_services'; -import { createSavedSearchesLoader } from './saved_searches'; +import { __LEGACY } from './saved_searches'; import { registerFeature } from './register_feature'; import { buildServices } from './build_services'; import { @@ -61,6 +61,7 @@ import { replaceUrlHashQuery } from '../../kibana_utils/public/'; import { IndexPatternFieldEditorStart } from '../../../plugins/index_pattern_field_editor/public'; import { DeferredSpinner } from './shared'; import { ViewSavedSearchAction } from './application/embeddable/view_saved_search_action'; +import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; declare module '../../share/public' { export interface UrlGeneratorStateMapping { @@ -120,7 +121,9 @@ export interface DiscoverSetup { } export interface DiscoverStart { - savedSearchLoader: SavedObjectLoader; + __LEGACY: { + savedSearchLoader: SavedObjectLoader; + }; /** * @deprecated Use URL locator instead. URL generator will be removed. @@ -189,6 +192,7 @@ export interface DiscoverStartPlugins { savedObjects: SavedObjectsStart; usageCollection?: UsageCollectionSetup; indexPatternFieldEditor: IndexPatternFieldEditorStart; + spaces?: SpacesPluginStart; } /** @@ -410,10 +414,12 @@ export class DiscoverPlugin return { urlGenerator: this.urlGenerator, locator: this.locator, - savedSearchLoader: createSavedSearchesLoader({ - savedObjectsClient: core.savedObjects.client, - savedObjects: plugins.savedObjects, - }), + __LEGACY: { + savedSearchLoader: __LEGACY.createSavedSearchesLoader({ + savedObjectsClient: core.savedObjects.client, + savedObjects: plugins.savedObjects, + }), + }, }; } diff --git a/src/plugins/share/server/saved_objects/index.ts b/src/plugins/discover/public/saved_searches/constants.ts similarity index 85% rename from src/plugins/share/server/saved_objects/index.ts rename to src/plugins/discover/public/saved_searches/constants.ts index ff37efb9fec17..f8e191c263bd7 100644 --- a/src/plugins/share/server/saved_objects/index.ts +++ b/src/plugins/discover/public/saved_searches/constants.ts @@ -6,4 +6,5 @@ * Side Public License, v 1. */ -export { url } from './url'; +/** @internal **/ +export const SAVED_SEARCH_TYPE = 'search'; diff --git a/src/plugins/discover/public/saved_searches/get_saved_searches.test.ts b/src/plugins/discover/public/saved_searches/get_saved_searches.test.ts new file mode 100644 index 0000000000000..755831e7009ed --- /dev/null +++ b/src/plugins/discover/public/saved_searches/get_saved_searches.test.ts @@ -0,0 +1,144 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { SavedObjectsStart } from '../../../../core/public'; +import type { DataPublicPluginStart } from '../../../data/public'; + +import { savedObjectsServiceMock } from '../../../../core/public/mocks'; +import { dataPluginMock } from '../../../data/public/mocks'; + +import { getSavedSearch } from './get_saved_searches'; + +describe('getSavedSearch', () => { + let search: DataPublicPluginStart['search']; + let savedObjectsClient: SavedObjectsStart['client']; + + beforeEach(() => { + savedObjectsClient = savedObjectsServiceMock.createStartContract().client; + search = dataPluginMock.createStartContract().search; + }); + + test('should return empty saved search in case of no id', async () => { + const savedSearch = await getSavedSearch(undefined, { savedObjectsClient, search }); + + expect(search.searchSource.createEmpty).toHaveBeenCalled(); + expect(savedSearch).toHaveProperty('searchSource'); + }); + + test('should throw an error if so not found', async () => { + let errorMessage = 'No error thrown.'; + savedObjectsClient.resolve = jest.fn().mockReturnValue({ + saved_object: { + attributes: {}, + error: { + statusCode: 404, + error: 'Not Found', + message: 'Saved object [search/ccf1af80-2297-11ec-86e0-1155ffb9c7a7] not found', + }, + id: 'ccf1af80-2297-11ec-86e0-1155ffb9c7a7', + type: 'search', + references: [], + }, + }); + + try { + await getSavedSearch('ccf1af80-2297-11ec-86e0-1155ffb9c7a7', { + savedObjectsClient, + search, + }); + } catch (error) { + errorMessage = error.message; + } + + expect(errorMessage).toBe( + 'Could not locate that search (id: ccf1af80-2297-11ec-86e0-1155ffb9c7a7)' + ); + }); + + test('should find saved search', async () => { + savedObjectsClient.resolve = jest.fn().mockReturnValue({ + saved_object: { + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: + '{"query":{"query":"","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', + }, + title: 'test1', + sort: [['order_date', 'desc']], + columns: ['_source'], + description: 'description', + grid: {}, + hideChart: false, + }, + id: 'ccf1af80-2297-11ec-86e0-1155ffb9c7a7', + type: 'search', + references: [ + { + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + type: 'index-pattern', + }, + ], + namespaces: ['default'], + }, + outcome: 'exactMatch', + }); + + const savedSearch = await getSavedSearch('ccf1af80-2297-11ec-86e0-1155ffb9c7a7', { + savedObjectsClient, + search, + }); + + expect(savedObjectsClient.resolve).toHaveBeenCalled(); + expect(savedSearch).toMatchInlineSnapshot(` + Object { + "columns": Array [ + "_source", + ], + "description": "description", + "grid": Object {}, + "hideChart": false, + "id": "ccf1af80-2297-11ec-86e0-1155ffb9c7a7", + "searchSource": Object { + "create": [MockFunction], + "createChild": [MockFunction], + "createCopy": [MockFunction], + "destroy": [MockFunction], + "fetch": [MockFunction], + "fetch$": [MockFunction], + "getField": [MockFunction], + "getFields": [MockFunction], + "getId": [MockFunction], + "getOwnField": [MockFunction], + "getParent": [MockFunction], + "getSearchRequestBody": [MockFunction], + "getSerializedFields": [MockFunction], + "history": Array [], + "onRequestStart": [MockFunction], + "removeField": [MockFunction], + "serialize": [MockFunction], + "setField": [MockFunction], + "setFields": [MockFunction], + "setParent": [MockFunction], + "setPreferredSearchStrategyId": [MockFunction], + }, + "sharingSavedObjectProps": Object { + "aliasTargetId": undefined, + "errorJSON": undefined, + "outcome": "exactMatch", + }, + "sort": Array [ + Array [ + "order_date", + "desc", + ], + ], + "title": "test1", + } + `); + }); +}); diff --git a/src/plugins/discover/public/saved_searches/get_saved_searches.ts b/src/plugins/discover/public/saved_searches/get_saved_searches.ts new file mode 100644 index 0000000000000..32c50f691fe42 --- /dev/null +++ b/src/plugins/discover/public/saved_searches/get_saved_searches.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { SavedObjectsStart } from '../../../../core/public'; +import type { DataPublicPluginStart } from '../../../data/public'; +import type { SavedSearchAttributes, SavedSearch } from './types'; + +import { SAVED_SEARCH_TYPE } from './constants'; +import { fromSavedSearchAttributes } from './saved_searches_utils'; +import { injectSearchSourceReferences, parseSearchSourceJSON } from '../../../data/public'; +import { SavedObjectNotFound } from '../../../kibana_utils/public'; + +import type { SpacesApi } from '../../../../../x-pack/plugins/spaces/public'; + +interface GetSavedSearchDependencies { + search: DataPublicPluginStart['search']; + savedObjectsClient: SavedObjectsStart['client']; + spaces?: SpacesApi; +} + +const getEmptySavedSearch = ({ + search, +}: { + search: DataPublicPluginStart['search']; +}): SavedSearch => ({ + searchSource: search.searchSource.createEmpty(), +}); + +const findSavedSearch = async ( + savedSearchId: string, + { search, savedObjectsClient, spaces }: GetSavedSearchDependencies +) => { + const so = await savedObjectsClient.resolve<SavedSearchAttributes>( + SAVED_SEARCH_TYPE, + savedSearchId + ); + + if (!so.saved_object || so.saved_object.error) { + throw new SavedObjectNotFound(SAVED_SEARCH_TYPE, savedSearchId); + } + + const savedSearch = so.saved_object; + + const parsedSearchSourceJSON = parseSearchSourceJSON( + savedSearch.attributes.kibanaSavedObjectMeta?.searchSourceJSON ?? '{}' + ); + + const searchSourceValues = injectSearchSourceReferences( + parsedSearchSourceJSON as Parameters<typeof injectSearchSourceReferences>[0], + savedSearch.references + ); + + return fromSavedSearchAttributes( + savedSearchId, + savedSearch.attributes, + await search.searchSource.create(searchSourceValues), + { + outcome: so.outcome, + aliasTargetId: so.alias_target_id, + errorJSON: + so.outcome === 'conflict' && spaces + ? JSON.stringify({ + targetType: SAVED_SEARCH_TYPE, + sourceId: savedSearchId, + targetSpace: (await spaces.getActiveSpace()).id, + }) + : undefined, + } + ); +}; + +/** @public **/ +export const getSavedSearch = async ( + savedSearchId: string | undefined, + dependencies: GetSavedSearchDependencies +) => { + return savedSearchId + ? findSavedSearch(savedSearchId, dependencies) + : getEmptySavedSearch(dependencies); +}; diff --git a/src/plugins/discover/public/saved_searches/index.ts b/src/plugins/discover/public/saved_searches/index.ts index 86564cc5d6eca..6870fa5e6d617 100644 --- a/src/plugins/discover/public/saved_searches/index.ts +++ b/src/plugins/discover/public/saved_searches/index.ts @@ -6,5 +6,25 @@ * Side Public License, v 1. */ -export { createSavedSearchesLoader } from './saved_searches'; -export { SavedSearch, SavedSearchLoader } from './types'; +import { createSavedSearchesLoader } from './legacy/saved_searches'; + +export { getSavedSearch } from './get_saved_searches'; +export { + getSavedSearchUrl, + getSavedSearchFullPathUrl, + getSavedSearchUrlConflictMessage, + throwErrorOnSavedSearchUrlConflict, +} from './saved_searches_utils'; +export { useSavedSearchAliasMatchRedirect } from './saved_search_alias_match_redirect'; +export { SavedSearchURLConflictCallout } from './saved_search_url_conflict_callout'; +export { saveSavedSearch, SaveSavedSearchOptions } from './save_saved_searches'; + +export { SAVED_SEARCH_TYPE } from './constants'; + +export type { SavedSearch } from './types'; +export type { LegacySavedSearch, SavedSearchLoader, SortOrder } from './legacy/types'; + +/** @deprecated __LEGACY object will be removed in v8**/ +export const __LEGACY = { + createSavedSearchesLoader, +}; diff --git a/src/plugins/discover/public/saved_searches/_saved_search.ts b/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts similarity index 80% rename from src/plugins/discover/public/saved_searches/_saved_search.ts rename to src/plugins/discover/public/saved_searches/legacy/_saved_search.ts index 56533ed20b31e..154f91f5582b3 100644 --- a/src/plugins/discover/public/saved_searches/_saved_search.ts +++ b/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts @@ -6,11 +6,14 @@ * Side Public License, v 1. */ -import { SavedObject, SavedObjectsStart } from '../../../saved_objects/public'; +import type { SavedObject, SavedObjectsStart } from '../../../../saved_objects/public'; +import { SAVED_SEARCH_TYPE } from '../constants'; +import { getSavedSearchFullPathUrl } from '../saved_searches_utils'; +/** @deprecated **/ export function createSavedSearchClass(savedObjects: SavedObjectsStart) { class SavedSearch extends savedObjects.SavedObjectClass { - public static type: string = 'search'; + public static type: string = SAVED_SEARCH_TYPE; public static mapping = { title: 'text', description: 'text', @@ -31,7 +34,7 @@ export function createSavedSearchClass(savedObjects: SavedObjectsStart) { constructor(id: string) { super({ id, - type: 'search', + type: SAVED_SEARCH_TYPE, mapping: { title: 'text', description: 'text', @@ -54,7 +57,7 @@ export function createSavedSearchClass(savedObjects: SavedObjectsStart) { }); this.showInRecentlyAccessed = true; this.id = id; - this.getFullPath = () => `/app/discover#/view/${String(id)}`; + this.getFullPath = () => getSavedSearchFullPathUrl(String(id)); } } diff --git a/src/plugins/presentation_util/public/components/controls/index.ts b/src/plugins/discover/public/saved_searches/legacy/index.ts similarity index 73% rename from src/plugins/presentation_util/public/components/controls/index.ts rename to src/plugins/discover/public/saved_searches/legacy/index.ts index 5c2d5b68ae2e0..0bfed6f57b9f5 100644 --- a/src/plugins/presentation_util/public/components/controls/index.ts +++ b/src/plugins/discover/public/saved_searches/legacy/index.ts @@ -5,3 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + +export { createSavedSearchesLoader } from './saved_searches'; +export { LegacySavedSearch, SavedSearchLoader } from './types'; diff --git a/src/plugins/discover/public/saved_searches/saved_searches.ts b/src/plugins/discover/public/saved_searches/legacy/saved_searches.ts similarity index 78% rename from src/plugins/discover/public/saved_searches/saved_searches.ts rename to src/plugins/discover/public/saved_searches/legacy/saved_searches.ts index 0fe693dcd2ebe..58bed080d0249 100644 --- a/src/plugins/discover/public/saved_searches/saved_searches.ts +++ b/src/plugins/discover/public/saved_searches/legacy/saved_searches.ts @@ -6,15 +6,17 @@ * Side Public License, v 1. */ -import { SavedObjectsClientContract } from 'kibana/public'; -import { SavedObjectLoader, SavedObjectsStart } from '../../../saved_objects/public'; +import type { SavedObjectsClientContract } from 'kibana/public'; +import { SavedObjectLoader, SavedObjectsStart } from '../../../../saved_objects/public'; import { createSavedSearchClass } from './_saved_search'; +import { getSavedSearchUrl } from '../saved_searches_utils'; interface Services { savedObjectsClient: SavedObjectsClientContract; savedObjects: SavedObjectsStart; } +/** @deprecated **/ export function createSavedSearchesLoader({ savedObjectsClient, savedObjects }: Services) { const SavedSearchClass = createSavedSearchClass(savedObjects); const savedSearchLoader = new SavedObjectLoader(SavedSearchClass, savedObjectsClient); @@ -25,7 +27,7 @@ export function createSavedSearchesLoader({ savedObjectsClient, savedObjects }: nouns: 'saved searches', }; - savedSearchLoader.urlFor = (id: string) => (id ? `#/view/${encodeURIComponent(id)}` : '#/'); + savedSearchLoader.urlFor = getSavedSearchUrl; return savedSearchLoader; } diff --git a/src/plugins/discover/public/saved_searches/legacy/types.ts b/src/plugins/discover/public/saved_searches/legacy/types.ts new file mode 100644 index 0000000000000..e55422ff26a7b --- /dev/null +++ b/src/plugins/discover/public/saved_searches/legacy/types.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { ISearchSource } from '../../../../data/public'; +import type { SavedObjectSaveOpts } from '../../../../saved_objects/public'; +import type { DiscoverGridSettings } from '../../application/components/discover_grid/types'; + +export type SortOrder = [string, string]; + +/** @deprecated **/ +export interface LegacySavedSearch { + readonly id: string; + title: string; + searchSource: ISearchSource; + description?: string; + columns: string[]; + sort: SortOrder[]; + grid: DiscoverGridSettings; + destroy: () => void; + save: (saveOptions: SavedObjectSaveOpts) => Promise<string>; + copyOnSave?: boolean; + hideChart?: boolean; +} + +/** @deprecated **/ +export interface SavedSearchLoader { + get: (id: string) => Promise<LegacySavedSearch>; + urlFor: (id: string) => string; +} diff --git a/src/plugins/discover/public/saved_searches/save_saved_searches.test.ts b/src/plugins/discover/public/saved_searches/save_saved_searches.test.ts new file mode 100644 index 0000000000000..eabbfe7f9419f --- /dev/null +++ b/src/plugins/discover/public/saved_searches/save_saved_searches.test.ts @@ -0,0 +1,117 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { SavedObjectsStart } from '../../../../core/public'; + +import { savedObjectsServiceMock } from '../../../../core/public/mocks'; +import { dataPluginMock } from '../../../data/public/mocks'; + +import { saveSavedSearch } from './save_saved_searches'; +import type { SavedSearch } from './types'; + +describe('saveSavedSearch', () => { + let savedObjectsClient: SavedObjectsStart['client']; + let savedSearch: SavedSearch; + + beforeEach(() => { + savedObjectsClient = savedObjectsServiceMock.createStartContract().client; + const searchSource = dataPluginMock.createStartContract().search.searchSource.createEmpty(); + + savedSearch = { + id: 'id', + title: 'title', + searchSource: { + ...searchSource, + serialize: () => ({ + searchSourceJSON: '{}', + references: [], + }), + }, + sharingSavedObjectProps: { + outcome: 'aliasMatch', + }, + } as SavedSearch; + }); + + describe('onTitleDuplicate', () => { + test('should check for title duplicating', async () => { + savedObjectsClient.find = jest.fn().mockReturnValue({ + savedObjects: [{ get: () => 'title' }], + }); + const onTitleDuplicate = jest.fn(); + + await saveSavedSearch( + savedSearch, + { + onTitleDuplicate, + copyOnSave: true, + }, + savedObjectsClient + ); + + expect(onTitleDuplicate).toHaveBeenCalled(); + }); + + test('should not check for title duplicating for saving existing search', async () => { + savedObjectsClient.find = jest.fn().mockReturnValue({ + savedObjects: [{ get: () => 'title' }], + }); + const onTitleDuplicate = jest.fn(); + + await saveSavedSearch( + savedSearch, + { + onTitleDuplicate, + copyOnSave: false, + }, + savedObjectsClient + ); + + expect(onTitleDuplicate).not.toHaveBeenCalled(); + }); + }); + + test('should call savedObjectsClient.create for saving new search', async () => { + delete savedSearch.id; + + await saveSavedSearch(savedSearch, {}, savedObjectsClient); + + expect(savedObjectsClient.create).toHaveBeenCalledWith( + 'search', + { + columns: [], + description: '', + grid: {}, + hideChart: false, + kibanaSavedObjectMeta: { searchSourceJSON: '{}' }, + sort: [], + title: 'title', + }, + { references: [] } + ); + }); + + test('should call savedObjectsClient.update for saving existing search', async () => { + await saveSavedSearch(savedSearch, {}, savedObjectsClient); + + expect(savedObjectsClient.update).toHaveBeenCalledWith( + 'search', + 'id', + { + columns: [], + description: '', + grid: {}, + hideChart: false, + kibanaSavedObjectMeta: { searchSourceJSON: '{}' }, + sort: [], + title: 'title', + }, + { references: [] } + ); + }); +}); diff --git a/src/plugins/discover/public/saved_searches/save_saved_searches.ts b/src/plugins/discover/public/saved_searches/save_saved_searches.ts new file mode 100644 index 0000000000000..c3440bdb7696a --- /dev/null +++ b/src/plugins/discover/public/saved_searches/save_saved_searches.ts @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { SavedObjectsStart } from 'kibana/public'; +import type { SavedSearch, SavedSearchAttributes } from './types'; + +import { SAVED_SEARCH_TYPE } from './constants'; +import { toSavedSearchAttributes } from './saved_searches_utils'; + +export interface SaveSavedSearchOptions { + onTitleDuplicate?: () => void; + isTitleDuplicateConfirmed?: boolean; + copyOnSave?: boolean; +} + +const hasDuplicatedTitle = async ( + title: string, + savedObjectsClient: SavedObjectsStart['client'] +): Promise<boolean | void> => { + if (!title) { + return; + } + + const response = await savedObjectsClient.find({ + type: SAVED_SEARCH_TYPE, + perPage: 10, + search: `"${title}"`, + searchFields: ['title'], + fields: ['title'], + }); + + return response.savedObjects.some( + (obj) => obj.get('title').toLowerCase() === title.toLowerCase() + ); +}; + +/** @internal **/ +export const saveSavedSearch = async ( + savedSearch: SavedSearch, + options: SaveSavedSearchOptions, + savedObjectsClient: SavedObjectsStart['client'] +): Promise<string | undefined> => { + const isNew = options.copyOnSave || !savedSearch.id; + + if (savedSearch.title) { + if ( + isNew && + !options.isTitleDuplicateConfirmed && + options.onTitleDuplicate && + (await hasDuplicatedTitle(savedSearch.title, savedObjectsClient)) + ) { + options.onTitleDuplicate(); + return; + } + } + + const { searchSourceJSON, references } = savedSearch.searchSource.serialize(); + const resp = isNew + ? await savedObjectsClient.create<SavedSearchAttributes>( + SAVED_SEARCH_TYPE, + toSavedSearchAttributes(savedSearch, searchSourceJSON), + { + references, + } + ) + : await savedObjectsClient.update<SavedSearchAttributes>( + SAVED_SEARCH_TYPE, + savedSearch.id!, + toSavedSearchAttributes(savedSearch, searchSourceJSON), + { + references, + } + ); + + return resp?.id; +}; diff --git a/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.test.ts b/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.test.ts new file mode 100644 index 0000000000000..0a871061d2b19 --- /dev/null +++ b/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import type { History } from 'history'; + +import { useSavedSearchAliasMatchRedirect } from './saved_search_alias_match_redirect'; +import type { SavedSearch } from './types'; + +import { spacesPluginMock } from '../../../../../x-pack/plugins/spaces/public/mocks'; + +describe('useSavedSearchAliasMatchRedirect', () => { + let spaces: ReturnType<typeof spacesPluginMock.createStartContract>; + let history: () => History; + + beforeEach(() => { + spaces = spacesPluginMock.createStartContract(); + history = () => + ({ + location: { + search: '?_g=foo', + }, + } as History); + }); + + test('should redirect in case of aliasMatch', () => { + const savedSearch = { + id: 'id', + sharingSavedObjectProps: { + outcome: 'aliasMatch', + aliasTargetId: 'aliasTargetId', + }, + } as SavedSearch; + + renderHook(() => useSavedSearchAliasMatchRedirect({ spaces, savedSearch, history })); + + expect(spaces.ui.redirectLegacyUrl).toHaveBeenCalledWith( + '#/view/aliasTargetId?_g=foo', + ' search' + ); + }); + + test('should not redirect if outcome !== aliasMatch', () => { + const savedSearch = { + id: 'id', + sharingSavedObjectProps: { + outcome: 'exactMatch', + }, + } as SavedSearch; + + renderHook(() => useSavedSearchAliasMatchRedirect({ spaces, savedSearch, history })); + + expect(spaces.ui.redirectLegacyUrl).not.toHaveBeenCalled(); + }); + + test('should not redirect if aliasTargetId is not defined', () => { + const savedSearch = { + id: 'id', + sharingSavedObjectProps: { + outcome: 'aliasMatch', + }, + } as SavedSearch; + + renderHook(() => useSavedSearchAliasMatchRedirect({ spaces, savedSearch, history })); + + expect(spaces.ui.redirectLegacyUrl).not.toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.ts b/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.ts new file mode 100644 index 0000000000000..3a88c1a2b1989 --- /dev/null +++ b/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { History } from 'history'; +import { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { getSavedSearchUrl } from './saved_searches_utils'; + +import type { SavedSearch } from './types'; +import type { SpacesApi } from '../../../../../x-pack/plugins/spaces/public'; + +interface SavedSearchAliasMatchRedirectProps { + savedSearch?: SavedSearch; + spaces?: SpacesApi; + history: () => History; +} + +export const useSavedSearchAliasMatchRedirect = ({ + savedSearch, + spaces, + history, +}: SavedSearchAliasMatchRedirectProps) => { + useEffect(() => { + async function aliasMatchRedirect() { + if (savedSearch) { + const { aliasTargetId, outcome } = savedSearch.sharingSavedObjectProps ?? {}; + + if (spaces && aliasTargetId && outcome === 'aliasMatch') { + await spaces.ui.redirectLegacyUrl( + `${getSavedSearchUrl(aliasTargetId)}${history().location.search}`, + i18n.translate('discover.savedSearchAliasMatchRedirect.objectNoun', { + defaultMessage: '{savedSearch} search', + values: { + savedSearch: savedSearch.title, + }, + }) + ); + } + } + } + + aliasMatchRedirect(); + }, [savedSearch, spaces, history]); +}; diff --git a/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.test.tsx b/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.test.tsx new file mode 100644 index 0000000000000..c92c15e771f64 --- /dev/null +++ b/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.test.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import type { History } from 'history'; + +import { mountWithIntl } from '@kbn/test/jest'; +import { SavedSearchURLConflictCallout } from './saved_search_url_conflict_callout'; +import type { SavedSearch } from './types'; + +import { spacesPluginMock } from '../../../../../x-pack/plugins/spaces/public/mocks'; + +describe('SavedSearchURLConflictCallout', () => { + let spaces: ReturnType<typeof spacesPluginMock.createStartContract>; + let history: () => History; + + beforeEach(() => { + spaces = spacesPluginMock.createStartContract(); + spaces.ui.components.getLegacyUrlConflict = jest.fn().mockReturnValue('callout'); + history = () => + ({ + location: { + search: '?_g=foo', + }, + } as History); + }); + + test("should render URLConflictCallout in case of id's conflicts", () => { + const savedSearch = { + id: 'id', + sharingSavedObjectProps: { + outcome: 'conflict', + aliasTargetId: 'aliasTargetId', + }, + } as SavedSearch; + + const component = mountWithIntl( + <SavedSearchURLConflictCallout spaces={spaces} savedSearch={savedSearch} history={history} /> + ); + + expect(component.children()).toMatchInlineSnapshot(`"callout"`); + }); + + test('should not render URLConflictCallout in case of no conflicts', () => { + const savedSearch = { + id: 'id', + sharingSavedObjectProps: {}, + } as SavedSearch; + + const component = mountWithIntl( + <SavedSearchURLConflictCallout spaces={spaces} savedSearch={savedSearch} history={history} /> + ); + + expect(component.children()).toMatchInlineSnapshot(`null`); + }); +}); diff --git a/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.ts b/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.ts new file mode 100644 index 0000000000000..fd07126c496cf --- /dev/null +++ b/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; +import type { History } from 'history'; +import { getSavedSearchUrl } from './saved_searches_utils'; + +import type { SavedSearch } from './types'; +import type { SpacesApi } from '../../../../../x-pack/plugins/spaces/public'; + +interface SavedSearchURLConflictCalloutProps { + savedSearch?: SavedSearch; + spaces?: SpacesApi; + history: () => History; +} + +export const SavedSearchURLConflictCallout = ({ + savedSearch, + spaces, + history, +}: SavedSearchURLConflictCalloutProps) => { + if (spaces && savedSearch?.id && savedSearch?.sharingSavedObjectProps?.outcome === 'conflict') { + const otherObjectId = savedSearch.sharingSavedObjectProps?.aliasTargetId; + + if (otherObjectId) { + return spaces.ui.components.getLegacyUrlConflict({ + objectNoun: i18n.translate('discover.savedSearchURLConflictCallout.objectNoun', { + defaultMessage: '{savedSearch} search', + values: { + savedSearch: savedSearch.title, + }, + }), + currentObjectId: savedSearch.id, + otherObjectPath: `${getSavedSearchUrl(otherObjectId)}${history().location.search}`, + otherObjectId, + }); + } + } + + return null; +}; diff --git a/src/plugins/discover/public/saved_searches/saved_searches_utils.test.ts b/src/plugins/discover/public/saved_searches/saved_searches_utils.test.ts new file mode 100644 index 0000000000000..12c73e86b3dc4 --- /dev/null +++ b/src/plugins/discover/public/saved_searches/saved_searches_utils.test.ts @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { + getSavedSearchUrl, + getSavedSearchFullPathUrl, + fromSavedSearchAttributes, + toSavedSearchAttributes, + throwErrorOnSavedSearchUrlConflict, +} from './saved_searches_utils'; + +import { createSearchSourceMock } from '../../../data/public/mocks'; + +import type { SavedSearchAttributes, SavedSearch } from './types'; + +describe('saved_searches_utils', () => { + describe('getSavedSearchUrl', () => { + test('should return valid saved search url', () => { + expect(getSavedSearchUrl()).toBe('#/'); + expect(getSavedSearchUrl('id')).toBe('#/view/id'); + }); + }); + + describe('getSavedSearchFullPathUrl', () => { + test('should return valid full path url', () => { + expect(getSavedSearchFullPathUrl()).toBe('/app/discover#/'); + expect(getSavedSearchFullPathUrl('id')).toBe('/app/discover#/view/id'); + }); + }); + + describe('fromSavedSearchAttributes', () => { + test('should convert attributes into SavedSearch', () => { + const attributes: SavedSearchAttributes = { + kibanaSavedObjectMeta: { searchSourceJSON: '{}' }, + title: 'saved search', + sort: [], + columns: ['a', 'b'], + description: 'foo', + grid: {}, + hideChart: true, + }; + + expect(fromSavedSearchAttributes('id', attributes, createSearchSourceMock(), {})) + .toMatchInlineSnapshot(` + Object { + "columns": Array [ + "a", + "b", + ], + "description": "foo", + "grid": Object {}, + "hideChart": true, + "id": "id", + "searchSource": SearchSource { + "dependencies": Object { + "getConfig": [MockFunction], + "onResponse": [MockFunction], + "search": [MockFunction], + }, + "fields": Object {}, + "getFieldName": [Function], + "history": Array [], + "id": "data_source1", + "inheritOptions": Object {}, + "parent": undefined, + "requestStartHandlers": Array [], + "searchStrategyId": undefined, + }, + "sharingSavedObjectProps": Object {}, + "sort": Array [], + "title": "saved search", + } + `); + }); + }); + + describe('throwErrorOnSavedSearchUrlConflict', () => { + test('should throw an error on url conflict', async () => { + let error = 'no error'; + + try { + await throwErrorOnSavedSearchUrlConflict({ + id: 'id', + sharingSavedObjectProps: { + outcome: 'conflict', + errorJSON: '{}', + }, + } as SavedSearch); + } catch (e) { + error = e.message; + } + + expect(error).toBe( + 'This search has the same URL as a legacy alias. Disable the alias to resolve this error : {}' + ); + }); + }); + + describe('toSavedSearchAttributes', () => { + test('should serialize SavedSearch attributes', () => { + const savedSearch: SavedSearch = { + id: 'id', + searchSource: createSearchSourceMock(), + title: 'title', + sort: [['a', 'asc']], + columns: ['c', 'd'], + description: 'description', + grid: {}, + hideChart: true, + }; + + expect(toSavedSearchAttributes(savedSearch, '{}')).toMatchInlineSnapshot(` + Object { + "columns": Array [ + "c", + "d", + ], + "description": "description", + "grid": Object {}, + "hideChart": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{}", + }, + "sort": Array [ + Array [ + "a", + "asc", + ], + ], + "title": "title", + } + `); + }); + }); +}); diff --git a/src/plugins/discover/public/saved_searches/saved_searches_utils.ts b/src/plugins/discover/public/saved_searches/saved_searches_utils.ts new file mode 100644 index 0000000000000..98ab2267a875e --- /dev/null +++ b/src/plugins/discover/public/saved_searches/saved_searches_utils.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { i18n } from '@kbn/i18n'; +import type { SavedSearchAttributes, SavedSearch } from './types'; + +export const getSavedSearchUrl = (id?: string) => (id ? `#/view/${encodeURIComponent(id)}` : '#/'); + +export const getSavedSearchFullPathUrl = (id?: string) => `/app/discover${getSavedSearchUrl(id)}`; + +export const getSavedSearchUrlConflictMessage = async (savedSearch: SavedSearch) => + i18n.translate('discover.savedSearchEmbeddable.legacyURLConflict.errorMessage', { + defaultMessage: `This search has the same URL as a legacy alias. Disable the alias to resolve this error : {json}`, + values: { + json: savedSearch.sharingSavedObjectProps?.errorJSON, + }, + }); + +export const throwErrorOnSavedSearchUrlConflict = async (savedSearch: SavedSearch) => { + if (savedSearch.sharingSavedObjectProps?.errorJSON) { + throw new Error(await getSavedSearchUrlConflictMessage(savedSearch)); + } +}; + +export const fromSavedSearchAttributes = ( + id: string, + attributes: SavedSearchAttributes, + searchSource: SavedSearch['searchSource'], + sharingSavedObjectProps: SavedSearch['sharingSavedObjectProps'] +): SavedSearch => ({ + id, + searchSource, + sharingSavedObjectProps, + title: attributes.title, + sort: attributes.sort, + columns: attributes.columns, + description: attributes.description, + grid: attributes.grid, + hideChart: attributes.hideChart, +}); + +export const toSavedSearchAttributes = ( + savedSearch: SavedSearch, + searchSourceJSON: string +): SavedSearchAttributes => ({ + kibanaSavedObjectMeta: { searchSourceJSON }, + title: savedSearch.title ?? '', + sort: savedSearch.sort ?? [], + columns: savedSearch.columns ?? [], + description: savedSearch.description ?? '', + grid: savedSearch.grid ?? {}, + hideChart: savedSearch.hideChart ?? false, +}); diff --git a/src/plugins/discover/public/saved_searches/types.ts b/src/plugins/discover/public/saved_searches/types.ts index b1c7b48d696b3..645ada901d5e5 100644 --- a/src/plugins/discover/public/saved_searches/types.ts +++ b/src/plugins/discover/public/saved_searches/types.ts @@ -6,26 +6,39 @@ * Side Public License, v 1. */ -import { SearchSource } from '../../../data/public'; -import { SavedObjectSaveOpts } from '../../../saved_objects/public'; -import { DiscoverGridSettings } from '../application/components/discover_grid/types'; +import type { ISearchSource } from '../../../data/public'; +import { DiscoverGridSettingsColumn } from '../application/components/discover_grid/types'; -export type SortOrder = [string, string]; -export interface SavedSearch { - readonly id: string; +/** @internal **/ +export interface SavedSearchAttributes { title: string; - searchSource: SearchSource; - description?: string; + sort: Array<[string, string]>; columns: string[]; - sort: SortOrder[]; - grid: DiscoverGridSettings; - destroy: () => void; - save: (saveOptions: SavedObjectSaveOpts) => Promise<string>; - lastSavedTitle?: string; - copyOnSave?: boolean; - hideChart?: boolean; + description: string; + grid: { + columns?: Record<string, DiscoverGridSettingsColumn>; + }; + hideChart: boolean; + kibanaSavedObjectMeta: { + searchSourceJSON: string; + }; } -export interface SavedSearchLoader { - get: (id: string) => Promise<SavedSearch>; - urlFor: (id: string) => string; + +/** @public **/ +export interface SavedSearch { + searchSource: ISearchSource; + id?: string; + title?: string; + sort?: Array<[string, string]>; + columns?: string[]; + description?: string; + grid?: { + columns?: Record<string, DiscoverGridSettingsColumn>; + }; + hideChart?: boolean; + sharingSavedObjectProps?: { + outcome?: 'aliasMatch' | 'exactMatch' | 'conflict'; + aliasTargetId?: string; + errorJSON?: string; + }; } diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index aa1b44da12bfc..82221fb8e8593 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -33,9 +33,10 @@ export const getUiSettings: () => Record<string, UiSettingsParams> = () => ({ name: i18n.translate('discover.advancedSettings.defaultColumnsTitle', { defaultMessage: 'Default columns', }), - value: ['_source'], + value: [], description: i18n.translate('discover.advancedSettings.defaultColumnsText', { - defaultMessage: 'Columns displayed by default in the Discovery tab', + defaultMessage: + 'Columns displayed by default in the Discover app. If empty, a summary of the document will be displayed.', }), category: ['discover'], schema: schema.arrayOf(schema.string()), diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index b3f1ad5d0bc1e..eb739e673cacd 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -24,6 +24,8 @@ { "path": "../kibana_react/tsconfig.json" }, { "path": "../kibana_legacy/tsconfig.json" }, { "path": "../index_pattern_field_editor/tsconfig.json"}, - { "path": "../field_formats/tsconfig.json" } + { "path": "../field_formats/tsconfig.json" }, + { "path": "../data_views/tsconfig.json" }, + { "path": "../../../x-pack/plugins/spaces/tsconfig.json" } ] } diff --git a/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.test.tsx b/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.test.tsx index 26ef7483bbbbd..0ae82872124a4 100644 --- a/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.test.tsx +++ b/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.test.tsx @@ -14,12 +14,6 @@ import { mountWithI18nProvider } from '@kbn/test/jest'; import { Frequency } from './types'; import { CronEditor } from './cron_editor'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - describe('CronEditor', () => { ['MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH', 'YEAR'].forEach((unit) => { test(`is rendered with a ${unit} frequency`, () => { diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/content.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/content.test.js.snap index 690875dc96900..5b9cde6e3c9a9 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/content.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/content.test.js.snap @@ -1,17 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should render content with markdown 1`] = ` -<Markdown - className="euiText" - markdown="I am *some* [content](https://en.wikipedia.org/wiki/Content) with \`markdown\`" - openLinksInNewTab={true} - whiteListedRules={ - Array [ - "backticks", - "emphasis", - "link", - "list", - ] - } -/> +<EuiMarkdownFormat> + I am *some* [content](https://en.wikipedia.org/wiki/Content) with \`markdown\` +</EuiMarkdownFormat> `; diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/footer.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/footer.test.js.snap index f054b5f5d9363..395fe30d48aca 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/footer.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/footer.test.js.snap @@ -1,35 +1,32 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`render 1`] = ` -<div> - <EuiHorizontalRule /> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" +<EuiFlexGroup + alignItems="center" + justifyContent="spaceBetween" +> + <EuiFlexItem + grow={false} > - <EuiFlexItem - grow={false} - > - <EuiText> - <p> - <FormattedMessage - defaultMessage="When all steps are complete, you're ready to explore your data." - id="home.exploreYourDataDescription" - values={Object {}} - /> - </p> - </EuiText> - </EuiFlexItem> - <EuiFlexItem - grow={false} + <EuiText> + <p> + <FormattedMessage + defaultMessage="When all steps are complete, you're ready to explore your data." + id="home.exploreYourDataDescription" + values={Object {}} + /> + </p> + </EuiText> + </EuiFlexItem> + <EuiFlexItem + grow={false} + > + <EuiButton + fill={true} + href="/app/myapp" > - <EuiButton - fill={true} - href="/app/myapp" - > - launch myapp - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> -</div> + launch myapp + </EuiButton> + </EuiFlexItem> +</EuiFlexGroup> `; diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap index 073d20b4bf804..5235392121ab0 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap @@ -1,649 +1,693 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`render 1`] = ` -<div> - <EuiFlexGroup - justifyContent="spaceBetween" - responsive={false} - wrap={true} +<_EuiSplitPanelOuter> + <_EuiSplitPanelInner + color="subdued" + paddingSize="none" > - <EuiFlexItem - grow={false} + <EuiTabs + style={ + Object { + "padding": "0 24px", + } + } > - <EuiTitle - size="m" + <EuiTab + isSelected={true} + key="0" + onClick={[Function]} > - <h2> - title1 - </h2> - </EuiTitle> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> - </EuiFlexGroup> - <EuiTabs> - <EuiTab - isSelected={true} - key="0" - onClick={[Function]} - > - OSX - </EuiTab> - <EuiTab - isSelected={false} - key="1" - onClick={[Function]} + OSX + </EuiTab> + <EuiTab + isSelected={false} + key="1" + onClick={[Function]} + > + Windows + </EuiTab> + </EuiTabs> + </_EuiSplitPanelInner> + <_EuiSplitPanelInner + paddingSize="l" + > + <EuiFlexGroup + justifyContent="spaceBetween" + responsive={false} + wrap={true} > - Windows - </EuiTab> - </EuiTabs> - <EuiSpacer - size="m" - /> - <EuiSteps - firstStepNumber={1} - steps={ - Array [ - Object { - "children": <Instruction - commands={ - Array [ - "do stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 0, - "title": "step 1", - }, - Object { - "children": <Instruction - commands={ - Array [ - "do more stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 1, - "title": "step 2", - }, - ] - } - /> -</div> + <EuiFlexItem + grow={false} + > + <EuiTitle + size="m" + > + <h2> + title1 + </h2> + </EuiTitle> + </EuiFlexItem> + <EuiFlexItem + grow={false} + /> + </EuiFlexGroup> + <EuiSpacer /> + <EuiSteps + firstStepNumber={1} + steps={ + Array [ + Object { + "children": <Instruction + commands={ + Array [ + "do stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 0, + "title": "step 1", + }, + Object { + "children": <Instruction + commands={ + Array [ + "do more stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 1, + "title": "step 2", + }, + ] + } + titleSize="xs" + /> + </_EuiSplitPanelInner> +</_EuiSplitPanelOuter> `; exports[`statusCheckState checking status 1`] = ` -<div> - <EuiFlexGroup - justifyContent="spaceBetween" - responsive={false} - wrap={true} +<_EuiSplitPanelOuter> + <_EuiSplitPanelInner + color="subdued" + paddingSize="none" > - <EuiFlexItem - grow={false} + <EuiTabs + style={ + Object { + "padding": "0 24px", + } + } > - <EuiTitle - size="m" + <EuiTab + isSelected={true} + key="0" + onClick={[Function]} > - <h2> - title1 - </h2> - </EuiTitle> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> - </EuiFlexGroup> - <EuiTabs> - <EuiTab - isSelected={true} - key="0" - onClick={[Function]} - > - OSX - </EuiTab> - <EuiTab - isSelected={false} - key="1" - onClick={[Function]} + OSX + </EuiTab> + <EuiTab + isSelected={false} + key="1" + onClick={[Function]} + > + Windows + </EuiTab> + </EuiTabs> + </_EuiSplitPanelInner> + <_EuiSplitPanelInner + paddingSize="l" + > + <EuiFlexGroup + justifyContent="spaceBetween" + responsive={false} + wrap={true} > - Windows - </EuiTab> - </EuiTabs> - <EuiSpacer - size="m" - /> - <EuiSteps - firstStepNumber={1} - steps={ - Array [ - Object { - "children": <Instruction - commands={ - Array [ - "do stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 0, - "title": "step 1", - }, - Object { - "children": <Instruction - commands={ - Array [ - "do more stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 1, - "title": "step 2", - }, - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <Content - text="custom status check description" - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} + <EuiFlexItem + grow={false} + > + <EuiTitle + size="m" + > + <h2> + title1 + </h2> + </EuiTitle> + </EuiFlexItem> + <EuiFlexItem + grow={false} + /> + </EuiFlexGroup> + <EuiSpacer /> + <EuiSteps + firstStepNumber={1} + steps={ + Array [ + Object { + "children": <Instruction + commands={ + Array [ + "do stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 0, + "title": "step 1", + }, + Object { + "children": <Instruction + commands={ + Array [ + "do more stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 1, + "title": "step 2", + }, + Object { + "children": <React.Fragment> + <Content + text="custom status check description" + /> + <EuiSpacer + size="s" + /> + <EuiButton + isLoading={true} + onClick={[Function]} > - <EuiButton - isLoading={true} - onClick={[Function]} - > - custom btn label - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - </React.Fragment>, - "key": "checkStatusStep", - "status": "incomplete", - "title": "custom title", - }, - ] - } - /> -</div> + custom btn label + </EuiButton> + </React.Fragment>, + "key": "checkStatusStep", + "status": "incomplete", + "title": "custom title", + }, + ] + } + titleSize="xs" + /> + </_EuiSplitPanelInner> +</_EuiSplitPanelOuter> `; exports[`statusCheckState failed status check - error 1`] = ` -<div> - <EuiFlexGroup - justifyContent="spaceBetween" - responsive={false} - wrap={true} +<_EuiSplitPanelOuter> + <_EuiSplitPanelInner + color="subdued" + paddingSize="none" > - <EuiFlexItem - grow={false} + <EuiTabs + style={ + Object { + "padding": "0 24px", + } + } > - <EuiTitle - size="m" + <EuiTab + isSelected={true} + key="0" + onClick={[Function]} > - <h2> - title1 - </h2> - </EuiTitle> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> - </EuiFlexGroup> - <EuiTabs> - <EuiTab - isSelected={true} - key="0" - onClick={[Function]} - > - OSX - </EuiTab> - <EuiTab - isSelected={false} - key="1" - onClick={[Function]} + OSX + </EuiTab> + <EuiTab + isSelected={false} + key="1" + onClick={[Function]} + > + Windows + </EuiTab> + </EuiTabs> + </_EuiSplitPanelInner> + <_EuiSplitPanelInner + paddingSize="l" + > + <EuiFlexGroup + justifyContent="spaceBetween" + responsive={false} + wrap={true} > - Windows - </EuiTab> - </EuiTabs> - <EuiSpacer - size="m" - /> - <EuiSteps - firstStepNumber={1} - steps={ - Array [ - Object { - "children": <Instruction - commands={ - Array [ - "do stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 0, - "title": "step 1", - }, - Object { - "children": <Instruction - commands={ - Array [ - "do more stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 1, - "title": "step 2", - }, - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <Content - text="custom status check description" - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} + <EuiFlexItem + grow={false} + > + <EuiTitle + size="m" + > + <h2> + title1 + </h2> + </EuiTitle> + </EuiFlexItem> + <EuiFlexItem + grow={false} + /> + </EuiFlexGroup> + <EuiSpacer /> + <EuiSteps + firstStepNumber={1} + steps={ + Array [ + Object { + "children": <Instruction + commands={ + Array [ + "do stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 0, + "title": "step 1", + }, + Object { + "children": <Instruction + commands={ + Array [ + "do more stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 1, + "title": "step 2", + }, + Object { + "children": <React.Fragment> + <Content + text="custom status check description" + /> + <EuiSpacer + size="s" + /> + <EuiButton + isLoading={false} + onClick={[Function]} > - <EuiButton - isLoading={false} - onClick={[Function]} - > - custom btn label - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - <EuiCallOut - color="warning" - title="custom error msg" - /> - </React.Fragment>, - "key": "checkStatusStep", - "status": "danger", - "title": "custom title", - }, - ] - } - /> -</div> + custom btn label + </EuiButton> + <React.Fragment> + <EuiSpacer + size="s" + /> + <EuiCallOut + color="warning" + title="custom error msg" + /> + </React.Fragment> + </React.Fragment>, + "key": "checkStatusStep", + "status": "danger", + "title": "custom title", + }, + ] + } + titleSize="xs" + /> + </_EuiSplitPanelInner> +</_EuiSplitPanelOuter> `; exports[`statusCheckState failed status check - no data 1`] = ` -<div> - <EuiFlexGroup - justifyContent="spaceBetween" - responsive={false} - wrap={true} +<_EuiSplitPanelOuter> + <_EuiSplitPanelInner + color="subdued" + paddingSize="none" > - <EuiFlexItem - grow={false} + <EuiTabs + style={ + Object { + "padding": "0 24px", + } + } > - <EuiTitle - size="m" + <EuiTab + isSelected={true} + key="0" + onClick={[Function]} > - <h2> - title1 - </h2> - </EuiTitle> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> - </EuiFlexGroup> - <EuiTabs> - <EuiTab - isSelected={true} - key="0" - onClick={[Function]} - > - OSX - </EuiTab> - <EuiTab - isSelected={false} - key="1" - onClick={[Function]} + OSX + </EuiTab> + <EuiTab + isSelected={false} + key="1" + onClick={[Function]} + > + Windows + </EuiTab> + </EuiTabs> + </_EuiSplitPanelInner> + <_EuiSplitPanelInner + paddingSize="l" + > + <EuiFlexGroup + justifyContent="spaceBetween" + responsive={false} + wrap={true} > - Windows - </EuiTab> - </EuiTabs> - <EuiSpacer - size="m" - /> - <EuiSteps - firstStepNumber={1} - steps={ - Array [ - Object { - "children": <Instruction - commands={ - Array [ - "do stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 0, - "title": "step 1", - }, - Object { - "children": <Instruction - commands={ - Array [ - "do more stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 1, - "title": "step 2", - }, - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <Content - text="custom status check description" - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} + <EuiFlexItem + grow={false} + > + <EuiTitle + size="m" + > + <h2> + title1 + </h2> + </EuiTitle> + </EuiFlexItem> + <EuiFlexItem + grow={false} + /> + </EuiFlexGroup> + <EuiSpacer /> + <EuiSteps + firstStepNumber={1} + steps={ + Array [ + Object { + "children": <Instruction + commands={ + Array [ + "do stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 0, + "title": "step 1", + }, + Object { + "children": <Instruction + commands={ + Array [ + "do more stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 1, + "title": "step 2", + }, + Object { + "children": <React.Fragment> + <Content + text="custom status check description" + /> + <EuiSpacer + size="s" + /> + <EuiButton + isLoading={false} + onClick={[Function]} > - <EuiButton - isLoading={false} - onClick={[Function]} - > - custom btn label - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - <EuiCallOut - color="warning" - title="custom error msg" - /> - </React.Fragment>, - "key": "checkStatusStep", - "status": "warning", - "title": "custom title", - }, - ] - } - /> -</div> + custom btn label + </EuiButton> + <React.Fragment> + <EuiSpacer + size="s" + /> + <EuiCallOut + color="warning" + title="custom error msg" + /> + </React.Fragment> + </React.Fragment>, + "key": "checkStatusStep", + "status": "warning", + "title": "custom title", + }, + ] + } + titleSize="xs" + /> + </_EuiSplitPanelInner> +</_EuiSplitPanelOuter> `; exports[`statusCheckState initial state - no check has been attempted 1`] = ` -<div> - <EuiFlexGroup - justifyContent="spaceBetween" - responsive={false} - wrap={true} +<_EuiSplitPanelOuter> + <_EuiSplitPanelInner + color="subdued" + paddingSize="none" > - <EuiFlexItem - grow={false} + <EuiTabs + style={ + Object { + "padding": "0 24px", + } + } > - <EuiTitle - size="m" + <EuiTab + isSelected={true} + key="0" + onClick={[Function]} > - <h2> - title1 - </h2> - </EuiTitle> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> - </EuiFlexGroup> - <EuiTabs> - <EuiTab - isSelected={true} - key="0" - onClick={[Function]} - > - OSX - </EuiTab> - <EuiTab - isSelected={false} - key="1" - onClick={[Function]} + OSX + </EuiTab> + <EuiTab + isSelected={false} + key="1" + onClick={[Function]} + > + Windows + </EuiTab> + </EuiTabs> + </_EuiSplitPanelInner> + <_EuiSplitPanelInner + paddingSize="l" + > + <EuiFlexGroup + justifyContent="spaceBetween" + responsive={false} + wrap={true} > - Windows - </EuiTab> - </EuiTabs> - <EuiSpacer - size="m" - /> - <EuiSteps - firstStepNumber={1} - steps={ - Array [ - Object { - "children": <Instruction - commands={ - Array [ - "do stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 0, - "title": "step 1", - }, - Object { - "children": <Instruction - commands={ - Array [ - "do more stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 1, - "title": "step 2", - }, - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <Content - text="custom status check description" - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} + <EuiFlexItem + grow={false} + > + <EuiTitle + size="m" + > + <h2> + title1 + </h2> + </EuiTitle> + </EuiFlexItem> + <EuiFlexItem + grow={false} + /> + </EuiFlexGroup> + <EuiSpacer /> + <EuiSteps + firstStepNumber={1} + steps={ + Array [ + Object { + "children": <Instruction + commands={ + Array [ + "do stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 0, + "title": "step 1", + }, + Object { + "children": <Instruction + commands={ + Array [ + "do more stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 1, + "title": "step 2", + }, + Object { + "children": <React.Fragment> + <Content + text="custom status check description" + /> + <EuiSpacer + size="s" + /> + <EuiButton + isLoading={true} + onClick={[Function]} > - <EuiButton - isLoading={true} - onClick={[Function]} - > - custom btn label - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - </React.Fragment>, - "key": "checkStatusStep", - "status": "incomplete", - "title": "custom title", - }, - ] - } - /> -</div> + custom btn label + </EuiButton> + </React.Fragment>, + "key": "checkStatusStep", + "status": "incomplete", + "title": "custom title", + }, + ] + } + titleSize="xs" + /> + </_EuiSplitPanelInner> +</_EuiSplitPanelOuter> `; exports[`statusCheckState successful status check 1`] = ` -<div> - <EuiFlexGroup - justifyContent="spaceBetween" - responsive={false} - wrap={true} +<_EuiSplitPanelOuter> + <_EuiSplitPanelInner + color="subdued" + paddingSize="none" > - <EuiFlexItem - grow={false} + <EuiTabs + style={ + Object { + "padding": "0 24px", + } + } > - <EuiTitle - size="m" + <EuiTab + isSelected={true} + key="0" + onClick={[Function]} > - <h2> - title1 - </h2> - </EuiTitle> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> - </EuiFlexGroup> - <EuiTabs> - <EuiTab - isSelected={true} - key="0" - onClick={[Function]} - > - OSX - </EuiTab> - <EuiTab - isSelected={false} - key="1" - onClick={[Function]} + OSX + </EuiTab> + <EuiTab + isSelected={false} + key="1" + onClick={[Function]} + > + Windows + </EuiTab> + </EuiTabs> + </_EuiSplitPanelInner> + <_EuiSplitPanelInner + paddingSize="l" + > + <EuiFlexGroup + justifyContent="spaceBetween" + responsive={false} + wrap={true} > - Windows - </EuiTab> - </EuiTabs> - <EuiSpacer - size="m" - /> - <EuiSteps - firstStepNumber={1} - steps={ - Array [ - Object { - "children": <Instruction - commands={ - Array [ - "do stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 0, - "title": "step 1", - }, - Object { - "children": <Instruction - commands={ - Array [ - "do more stuff in command line", - ] - } - isCloudEnabled={false} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - variantId="OSX" - />, - "key": 1, - "title": "step 2", - }, - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <Content - text="custom status check description" - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} + <EuiFlexItem + grow={false} + > + <EuiTitle + size="m" + > + <h2> + title1 + </h2> + </EuiTitle> + </EuiFlexItem> + <EuiFlexItem + grow={false} + /> + </EuiFlexGroup> + <EuiSpacer /> + <EuiSteps + firstStepNumber={1} + steps={ + Array [ + Object { + "children": <Instruction + commands={ + Array [ + "do stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 0, + "title": "step 1", + }, + Object { + "children": <Instruction + commands={ + Array [ + "do more stuff in command line", + ] + } + isCloudEnabled={false} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + variantId="OSX" + />, + "key": 1, + "title": "step 2", + }, + Object { + "children": <React.Fragment> + <Content + text="custom status check description" + /> + <EuiSpacer + size="s" + /> + <EuiButton + isLoading={false} + onClick={[Function]} > - <EuiButton - isLoading={false} - onClick={[Function]} - > - custom btn label - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - <EuiCallOut - color="success" - title="custom success msg" - /> - </React.Fragment>, - "key": "checkStatusStep", - "status": "complete", - "title": "custom title", - }, - ] - } - /> -</div> + custom btn label + </EuiButton> + <React.Fragment> + <EuiSpacer + size="s" + /> + <EuiCallOut + color="success" + title="custom success msg" + /> + </React.Fragment> + </React.Fragment>, + "key": "checkStatusStep", + "status": "complete", + "title": "custom title", + }, + ] + } + titleSize="xs" + /> + </_EuiSplitPanelInner> +</_EuiSplitPanelOuter> `; diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap index 410d29a42cac9..39bdda213acba 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap @@ -1,182 +1,118 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`props exportedFieldsUrl 1`] = ` -<EuiFlexGroup> - <EuiFlexItem> - <EuiFlexGroup - alignItems="center" - gutterSize="l" - > - <EuiFlexItem - grow={false} - > - <EuiTitle - size="l" +<EuiPageHeader + description={ + <React.Fragment> + <Content + text="this is a great tutorial about..." + /> + <React.Fragment> + <br /> + <EuiLink + href="exported_fields_url" + rel="noopener" + target="_blank" > - <h1> - Great tutorial - </h1> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - <Content - text="this is a great tutorial about..." - /> - <div> - <EuiSpacer /> - <EuiButton - href="exported_fields_url" - rel="noopener" - target="_blank" - > - <FormattedMessage - defaultMessage="View exported fields" - id="home.tutorial.introduction.viewButtonLabel" - values={Object {}} - /> - </EuiButton> - </div> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> -</EuiFlexGroup> + <FormattedMessage + defaultMessage="View exported fields" + id="home.tutorial.introduction.viewButtonLabel" + values={Object {}} + /> + </EuiLink> + </React.Fragment> + </React.Fragment> + } + pageTitle={ + <React.Fragment> + Great tutorial + </React.Fragment> + } +/> `; exports[`props iconType 1`] = ` -<EuiFlexGroup> - <EuiFlexItem> - <EuiFlexGroup - alignItems="center" - gutterSize="l" - > - <EuiFlexItem - grow={false} - > - <EuiIcon - size="xl" - title="" - type="logoElastic" - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <EuiTitle - size="l" - > - <h1> - Great tutorial - </h1> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - <Content - text="this is a great tutorial about..." - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> -</EuiFlexGroup> +<EuiPageHeader + description={ + <React.Fragment> + <Content + text="this is a great tutorial about..." + /> + </React.Fragment> + } + iconType="logoElastic" + pageTitle={ + <React.Fragment> + Great tutorial + </React.Fragment> + } +/> `; exports[`props isBeta 1`] = ` -<EuiFlexGroup> - <EuiFlexItem> - <EuiFlexGroup - alignItems="center" - gutterSize="l" - > - <EuiFlexItem - grow={false} - > - <EuiTitle - size="l" - > - <h1> - Great tutorial - - <EuiBetaBadge - label="Beta" - /> - </h1> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - <Content - text="this is a great tutorial about..." - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> -</EuiFlexGroup> +<EuiPageHeader + description={ + <React.Fragment> + <Content + text="this is a great tutorial about..." + /> + </React.Fragment> + } + pageTitle={ + <React.Fragment> + Great tutorial + <React.Fragment> + + <EuiBetaBadge + label="Beta" + /> + </React.Fragment> + </React.Fragment> + } +/> `; exports[`props previewUrl 1`] = ` -<EuiFlexGroup> - <EuiFlexItem> - <EuiFlexGroup - alignItems="center" - gutterSize="l" - > - <EuiFlexItem - grow={false} - > - <EuiTitle - size="l" - > - <h1> - Great tutorial - </h1> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - <Content - text="this is a great tutorial about..." - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <EuiImage - allowFullScreen={true} - alt="screenshot of primary dashboard." - fullScreenIconColor="dark" - hasShadow={true} - size="l" - url="preview_image_url" - /> - </EuiFlexItem> -</EuiFlexGroup> +<EuiPageHeader + description={ + <React.Fragment> + <Content + text="this is a great tutorial about..." + /> + </React.Fragment> + } + pageTitle={ + <React.Fragment> + Great tutorial + </React.Fragment> + } + rightSideItems={ + Array [ + <EuiImage + allowFullScreen={true} + alt="screenshot of primary dashboard." + fullScreenIconColor="dark" + size="l" + url="preview_image_url" + />, + ] + } +/> `; exports[`render 1`] = ` -<EuiFlexGroup> - <EuiFlexItem> - <EuiFlexGroup - alignItems="center" - gutterSize="l" - > - <EuiFlexItem - grow={false} - > - <EuiTitle - size="l" - > - <h1> - Great tutorial - </h1> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - <Content - text="this is a great tutorial about..." - /> - </EuiFlexItem> - <EuiFlexItem - grow={false} - /> -</EuiFlexGroup> +<EuiPageHeader + description={ + <React.Fragment> + <Content + text="this is a great tutorial about..." + /> + </React.Fragment> + } + pageTitle={ + <React.Fragment> + Great tutorial + </React.Fragment> + } +/> `; diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/saved_objects_installer.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/saved_objects_installer.test.js.snap index f643f2a22ea42..d970dd5416816 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/saved_objects_installer.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/saved_objects_installer.test.js.snap @@ -115,219 +115,124 @@ exports[`bulkCreate should display error message when bulkCreate request fails 1 ] } > - <EuiSteps - steps={ - Array [ - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <EuiText> - <p> - Imports index pattern, visualizations and pre-defined dashboards. - </p> - </EuiText> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <EuiButton - data-test-subj="loadSavedObjects" - isLoading={false} - onClick={[Function]} - > - Load Kibana objects - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - <EuiCallOut - color="warning" - data-test-subj="loadSavedObjects_failed" - title="Request failed, Error: simulated bulkRequest error" - /> - </React.Fragment>, - "key": "installStep", - "status": "incomplete", - "title": "Load Kibana objects", - }, - ] - } + <EuiTitle + size="m" + > + <h2 + className="euiTitle euiTitle--medium" + > + Load Kibana objects + </h2> + </EuiTitle> + <EuiFlexGroup + alignItems="center" + justifyContent="spaceBetween" > <div - className="euiSteps" + className="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive" > - <EuiStep - headingElement="p" - key="installStep" - status="incomplete" - step={1} - title="Load Kibana objects" - > + <EuiFlexItem> <div - className="euiStep" + className="euiFlexItem" > - <div - className="euiStep__titleWrapper" - > - <EuiStepNumber - className="euiStep__circle" - isHollow={true} - number={1} - status="incomplete" - titleSize="s" + <EuiText> + <div + className="euiText euiText--medium" > - <span - className="euiStepNumber euiStepNumber--incomplete euiStepNumber-isHollow euiStep__circle" - > - <EuiScreenReaderOnly> - <span - className="euiScreenReaderOnly" - > - Step 1 is incomplete - </span> - </EuiScreenReaderOnly> - <span - aria-hidden="true" - className="euiStepNumber__number" - > - 1 - </span> - </span> - </EuiStepNumber> - <EuiTitle - className="euiStep__title" - size="s" - > - <p - className="euiTitle euiTitle--small euiStep__title" - > - Load Kibana objects + <p> + Imports index pattern, visualizations and pre-defined dashboards. </p> - </EuiTitle> - </div> - <div - className="euiStep__content" + </div> + </EuiText> + </div> + </EuiFlexItem> + <EuiFlexItem + grow={false} + > + <div + className="euiFlexItem euiFlexItem--flexGrowZero" + > + <EuiButton + data-test-subj="loadSavedObjects" + isLoading={false} + onClick={[Function]} > - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <div - className="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive" - > - <EuiFlexItem> - <div - className="euiFlexItem" - > - <EuiText> - <div - className="euiText euiText--medium" - > - <p> - Imports index pattern, visualizations and pre-defined dashboards. - </p> - </div> - </EuiText> - </div> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <div - className="euiFlexItem euiFlexItem--flexGrowZero" - > - <EuiButton - data-test-subj="loadSavedObjects" - isLoading={false} - onClick={[Function]} - > - <EuiButtonDisplay - baseClassName="euiButton" - data-test-subj="loadSavedObjects" - disabled={false} - element="button" - isDisabled={false} - isLoading={false} - onClick={[Function]} - type="button" - > - <button - className="euiButton euiButton--primary" - data-test-subj="loadSavedObjects" - disabled={false} - onClick={[Function]} - style={ - Object { - "minWidth": undefined, - } - } - type="button" - > - <EuiButtonContent - className="euiButton__content" - iconSide="left" - isLoading={false} - textProps={ - Object { - "className": "euiButton__text", - } - } - > - <span - className="euiButtonContent euiButton__content" - > - <span - className="euiButton__text" - > - Load Kibana objects - </span> - </span> - </EuiButtonContent> - </button> - </EuiButtonDisplay> - </EuiButton> - </div> - </EuiFlexItem> - </div> - </EuiFlexGroup> - <EuiSpacer - size="s" - > - <div - className="euiSpacer euiSpacer--s" - /> - </EuiSpacer> - <EuiCallOut - color="warning" - data-test-subj="loadSavedObjects_failed" - title="Request failed, Error: simulated bulkRequest error" + <EuiButtonDisplay + baseClassName="euiButton" + data-test-subj="loadSavedObjects" + disabled={false} + element="button" + isDisabled={false} + isLoading={false} + onClick={[Function]} + type="button" > - <div - className="euiCallOut euiCallOut--warning" - data-test-subj="loadSavedObjects_failed" + <button + className="euiButton euiButton--primary" + data-test-subj="loadSavedObjects" + disabled={false} + onClick={[Function]} + style={ + Object { + "minWidth": undefined, + } + } + type="button" > - <div - className="euiCallOutHeader" + <EuiButtonContent + className="euiButton__content" + iconSide="left" + isLoading={false} + textProps={ + Object { + "className": "euiButton__text", + } + } > <span - className="euiCallOutHeader__title" + className="euiButtonContent euiButton__content" > - Request failed, Error: simulated bulkRequest error + <span + className="euiButton__text" + > + Load Kibana objects + </span> </span> - </div> - </div> - </EuiCallOut> - </div> + </EuiButtonContent> + </button> + </EuiButtonDisplay> + </EuiButton> </div> - </EuiStep> + </EuiFlexItem> </div> - </EuiSteps> + </EuiFlexGroup> + <EuiSpacer + size="s" + > + <div + className="euiSpacer euiSpacer--s" + /> + </EuiSpacer> + <EuiCallOut + color="warning" + data-test-subj="loadSavedObjects_failed" + title="Request failed, Error: simulated bulkRequest error" + > + <div + className="euiCallOut euiCallOut--warning" + data-test-subj="loadSavedObjects_failed" + > + <div + className="euiCallOutHeader" + > + <span + className="euiCallOutHeader__title" + > + Request failed, Error: simulated bulkRequest error + </span> + </div> + </div> + </EuiCallOut> </SavedObjectsInstallerUi> `; @@ -446,260 +351,161 @@ exports[`bulkCreate should display success message when bulkCreate is successful ] } > - <EuiSteps - steps={ - Array [ - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <EuiText> - <p> - Imports index pattern, visualizations and pre-defined dashboards. - </p> - </EuiText> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <EuiButton - data-test-subj="loadSavedObjects" - isLoading={false} - onClick={[Function]} - > - Load Kibana objects - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - <EuiCallOut - color="success" - data-test-subj="loadSavedObjects_success" - title="1 saved objects successfully added" - /> - </React.Fragment>, - "key": "installStep", - "status": "complete", - "title": "Load Kibana objects", - }, - ] - } + <EuiTitle + size="m" + > + <h2 + className="euiTitle euiTitle--medium" + > + Load Kibana objects + </h2> + </EuiTitle> + <EuiFlexGroup + alignItems="center" + justifyContent="spaceBetween" > <div - className="euiSteps" + className="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive" > - <EuiStep - headingElement="p" - key="installStep" - status="complete" - step={1} - title="Load Kibana objects" - > + <EuiFlexItem> <div - className="euiStep" + className="euiFlexItem" > - <div - className="euiStep__titleWrapper" - > - <EuiStepNumber - className="euiStep__circle" - isHollow={false} - number={1} - status="complete" - titleSize="s" - > - <span - className="euiStepNumber euiStepNumber--complete euiStep__circle" - > - <EuiIcon - aria-label="Step 1 is complete" - className="euiStepNumber__icon" - size="m" - type="check" - > - <span - aria-label="Step 1 is complete" - className="euiStepNumber__icon" - data-euiicon-type="check" - size="m" - /> - </EuiIcon> - </span> - </EuiStepNumber> - <EuiTitle - className="euiStep__title" - size="s" + <EuiText> + <div + className="euiText euiText--medium" > - <p - className="euiTitle euiTitle--small euiStep__title" - > - Load Kibana objects + <p> + Imports index pattern, visualizations and pre-defined dashboards. </p> - </EuiTitle> - </div> - <div - className="euiStep__content" + </div> + </EuiText> + </div> + </EuiFlexItem> + <EuiFlexItem + grow={false} + > + <div + className="euiFlexItem euiFlexItem--flexGrowZero" + > + <EuiButton + data-test-subj="loadSavedObjects" + isLoading={false} + onClick={[Function]} > - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" + <EuiButtonDisplay + baseClassName="euiButton" + data-test-subj="loadSavedObjects" + disabled={false} + element="button" + isDisabled={false} + isLoading={false} + onClick={[Function]} + type="button" > - <div - className="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive" - > - <EuiFlexItem> - <div - className="euiFlexItem" - > - <EuiText> - <div - className="euiText euiText--medium" - > - <p> - Imports index pattern, visualizations and pre-defined dashboards. - </p> - </div> - </EuiText> - </div> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <div - className="euiFlexItem euiFlexItem--flexGrowZero" - > - <EuiButton - data-test-subj="loadSavedObjects" - isLoading={false} - onClick={[Function]} - > - <EuiButtonDisplay - baseClassName="euiButton" - data-test-subj="loadSavedObjects" - disabled={false} - element="button" - isDisabled={false} - isLoading={false} - onClick={[Function]} - type="button" - > - <button - className="euiButton euiButton--primary" - data-test-subj="loadSavedObjects" - disabled={false} - onClick={[Function]} - style={ - Object { - "minWidth": undefined, - } - } - type="button" - > - <EuiButtonContent - className="euiButton__content" - iconSide="left" - isLoading={false} - textProps={ - Object { - "className": "euiButton__text", - } - } - > - <span - className="euiButtonContent euiButton__content" - > - <span - className="euiButton__text" - > - Load Kibana objects - </span> - </span> - </EuiButtonContent> - </button> - </EuiButtonDisplay> - </EuiButton> - </div> - </EuiFlexItem> - </div> - </EuiFlexGroup> - <EuiSpacer - size="s" - > - <div - className="euiSpacer euiSpacer--s" - /> - </EuiSpacer> - <EuiCallOut - color="success" - data-test-subj="loadSavedObjects_success" - title="1 saved objects successfully added" - > - <div - className="euiCallOut euiCallOut--success" - data-test-subj="loadSavedObjects_success" + <button + className="euiButton euiButton--primary" + data-test-subj="loadSavedObjects" + disabled={false} + onClick={[Function]} + style={ + Object { + "minWidth": undefined, + } + } + type="button" > - <div - className="euiCallOutHeader" + <EuiButtonContent + className="euiButton__content" + iconSide="left" + isLoading={false} + textProps={ + Object { + "className": "euiButton__text", + } + } > <span - className="euiCallOutHeader__title" + className="euiButtonContent euiButton__content" > - 1 saved objects successfully added + <span + className="euiButton__text" + > + Load Kibana objects + </span> </span> - </div> - </div> - </EuiCallOut> - </div> + </EuiButtonContent> + </button> + </EuiButtonDisplay> + </EuiButton> </div> - </EuiStep> + </EuiFlexItem> + </div> + </EuiFlexGroup> + <EuiSpacer + size="s" + > + <div + className="euiSpacer euiSpacer--s" + /> + </EuiSpacer> + <EuiCallOut + color="success" + data-test-subj="loadSavedObjects_success" + title="1 saved objects successfully added" + > + <div + className="euiCallOut euiCallOut--success" + data-test-subj="loadSavedObjects_success" + > + <div + className="euiCallOutHeader" + > + <span + className="euiCallOutHeader__title" + > + 1 saved objects successfully added + </span> + </div> </div> - </EuiSteps> + </EuiCallOut> </SavedObjectsInstallerUi> `; exports[`renders 1`] = ` -<EuiSteps - steps={ - Array [ - Object { - "children": <React.Fragment> - <EuiFlexGroup - alignItems="center" - justifyContent="spaceBetween" - > - <EuiFlexItem> - <EuiText> - <p> - Imports index pattern, visualizations and pre-defined dashboards. - </p> - </EuiText> - </EuiFlexItem> - <EuiFlexItem - grow={false} - > - <EuiButton - data-test-subj="loadSavedObjects" - isLoading={false} - onClick={[Function]} - > - Load Kibana objects - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer - size="s" - /> - </React.Fragment>, - "key": "installStep", - "status": "incomplete", - "title": "Load Kibana objects", - }, - ] - } -/> +<Fragment> + <EuiTitle + size="m" + > + <h2> + Load Kibana objects + </h2> + </EuiTitle> + <EuiFlexGroup + alignItems="center" + justifyContent="spaceBetween" + > + <EuiFlexItem> + <EuiText> + <p> + Imports index pattern, visualizations and pre-defined dashboards. + </p> + </EuiText> + </EuiFlexItem> + <EuiFlexItem + grow={false} + > + <EuiButton + data-test-subj="loadSavedObjects" + isLoading={false} + onClick={[Function]} + > + Load Kibana objects + </EuiButton> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer + size="s" + /> +</Fragment> `; diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap index ac697fae17f69..91dcdabd75dee 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap @@ -1,173 +1,146 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`isCloudEnabled is false should not render instruction toggle when ON_PREM_ELASTIC_CLOUD instructions are not provided 1`] = ` -<EuiPage - restrictWidth={1200} +<KibanaPageTemplate + template="empty" > - <EuiPageBody> - <div> - <InjectIntl(IntroductionUI) - description="tutorial used to drive jest tests" - title="jest test tutorial" - /> - <EuiSpacer /> - <div - className="eui-textCenter" - /> - <EuiSpacer /> - <EuiPanel - paddingSize="l" - > - <InjectIntl(InstructionSetUi) - instructionVariants={ - Array [ + <div> + <InjectIntl(IntroductionUI) + description="tutorial used to drive jest tests" + notices={null} + title="jest test tutorial" + /> + <EuiSpacer /> + <InjectIntl(InstructionSetUi) + instructionVariants={ + Array [ + Object { + "id": "platform id", + "instructions": Array [ Object { - "id": "platform id", - "instructions": Array [ - Object { - "title": "onPrem instructions", - }, - ], + "title": "onPrem instructions", }, - ] - } - isCloudEnabled={false} - key="0" - offset={1} - onStatusCheck={[Function]} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - setParameter={[Function]} - statusCheckState="NOT_CHECKED" - title="Instruction title" - /> - </EuiPanel> - </div> - </EuiPageBody> -</EuiPage> + ], + }, + ] + } + isCloudEnabled={false} + offset={1} + onStatusCheck={[Function]} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + setParameter={[Function]} + statusCheckState="NOT_CHECKED" + title="Instruction title" + /> + </div> +</KibanaPageTemplate> `; exports[`isCloudEnabled is false should render ON_PREM instructions with instruction toggle 1`] = ` -<EuiPage - restrictWidth={1200} +<KibanaPageTemplate + template="empty" > - <EuiPageBody> - <div> - <InjectIntl(IntroductionUI) - description="tutorial used to drive jest tests" - iconType="logoApache" - title="jest test tutorial" + <div> + <InjectIntl(IntroductionUI) + description="tutorial used to drive jest tests" + iconType="logoApache" + notices={null} + title="jest test tutorial" + /> + <EuiSpacer /> + <EuiFormRow + describedByIds={Array []} + display="row" + fullWidth={false} + hasChildLabel={true} + hasEmptyLabelSpace={false} + labelType="label" + > + <EuiButtonGroup + buttonSize="m" + color="text" + idSelected="onPrem" + isFullWidth={true} + legend="Deployment type" + onChange={[Function]} + options={ + Array [ + Object { + "data-test-subj": "selfManagedTutorial", + "id": "onPrem", + "label": "Self managed", + }, + Object { + "data-test-subj": "onCloudTutorial", + "id": "onPremElasticCloud", + "label": "Elastic Cloud", + }, + ] + } /> - <EuiSpacer /> - <div - className="eui-textCenter" - > - <EuiFlexGroup - justifyContent="center" - > - <EuiFlexItem - grow={false} - > - <EuiButtonGroup - color="primary" - idSelected="onPrem" - legend="Deployment type" - onChange={[Function]} - options={ - Array [ - Object { - "data-test-subj": "selfManagedTutorial", - "id": "onPrem", - "label": "Self managed", - }, - Object { - "data-test-subj": "onCloudTutorial", - "id": "onPremElasticCloud", - "label": "Elastic Cloud", - }, - ] - } - /> - </EuiFlexItem> - </EuiFlexGroup> - </div> - <EuiSpacer /> - <EuiPanel - paddingSize="l" - > - <InjectIntl(InstructionSetUi) - instructionVariants={ - Array [ + </EuiFormRow> + <EuiSpacer /> + <InjectIntl(InstructionSetUi) + instructionVariants={ + Array [ + Object { + "id": "platform id", + "instructions": Array [ Object { - "id": "platform id", - "instructions": Array [ - Object { - "title": "onPrem instructions", - }, - ], + "title": "onPrem instructions", }, - ] - } - isCloudEnabled={false} - key="0" - offset={1} - onStatusCheck={[Function]} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - setParameter={[Function]} - statusCheckState="NOT_CHECKED" - title="Instruction title" - /> - </EuiPanel> - </div> - </EuiPageBody> -</EuiPage> + ], + }, + ] + } + isCloudEnabled={false} + offset={1} + onStatusCheck={[Function]} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + setParameter={[Function]} + statusCheckState="NOT_CHECKED" + title="Instruction title" + /> + </div> +</KibanaPageTemplate> `; exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`] = ` -<EuiPage - restrictWidth={1200} +<KibanaPageTemplate + template="empty" > - <EuiPageBody> - <div> - <InjectIntl(IntroductionUI) - description="tutorial used to drive jest tests" - iconType="logoApache" - title="jest test tutorial" - /> - <EuiSpacer /> - <div - className="eui-textCenter" - /> - <EuiSpacer /> - <EuiPanel - paddingSize="l" - > - <InjectIntl(InstructionSetUi) - instructionVariants={ - Array [ + <div> + <InjectIntl(IntroductionUI) + description="tutorial used to drive jest tests" + iconType="logoApache" + notices={null} + title="jest test tutorial" + /> + <EuiSpacer /> + <InjectIntl(InstructionSetUi) + instructionVariants={ + Array [ + Object { + "id": "platform id", + "instructions": Array [ Object { - "id": "platform id", - "instructions": Array [ - Object { - "title": "elasticCloud instructions", - }, - ], + "title": "elasticCloud instructions", }, - ] - } - isCloudEnabled={true} - key="0" - offset={1} - onStatusCheck={[Function]} - paramValues={Object {}} - replaceTemplateStrings={[Function]} - setParameter={[Function]} - statusCheckState="NOT_CHECKED" - title="Instruction title" - /> - </EuiPanel> - </div> - </EuiPageBody> -</EuiPage> + ], + }, + ] + } + isCloudEnabled={true} + offset={1} + onStatusCheck={[Function]} + paramValues={Object {}} + replaceTemplateStrings={[Function]} + setParameter={[Function]} + statusCheckState="NOT_CHECKED" + title="Instruction title" + /> + </div> +</KibanaPageTemplate> `; diff --git a/src/plugins/home/public/application/components/tutorial/_tutorial.scss b/src/plugins/home/public/application/components/tutorial/_tutorial.scss index b517476885e2e..6d6ca4781346d 100644 --- a/src/plugins/home/public/application/components/tutorial/_tutorial.scss +++ b/src/plugins/home/public/application/components/tutorial/_tutorial.scss @@ -1,7 +1,3 @@ -.homTutorial__notFoundPanel { - background: $euiColorEmptyShade; - padding: $euiSizeL; -} .homTutorial__instruction { flex-shrink: 0; diff --git a/src/plugins/home/public/application/components/tutorial/content.js b/src/plugins/home/public/application/components/tutorial/content.js index 8b0e09d2eb851..d076957521eee 100644 --- a/src/plugins/home/public/application/components/tutorial/content.js +++ b/src/plugins/home/public/application/components/tutorial/content.js @@ -8,19 +8,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Markdown } from '../../../../../kibana_react/public'; - -const whiteListedRules = ['backticks', 'emphasis', 'link', 'list']; +import { EuiMarkdownFormat } from '@elastic/eui'; export function Content({ text }) { - return ( - <Markdown - className="euiText" - markdown={text} - openLinksInNewTab={true} - whiteListedRules={whiteListedRules} - /> - ); + return <EuiMarkdownFormat>{text}</EuiMarkdownFormat>; } Content.propTypes = { diff --git a/src/plugins/home/public/application/components/tutorial/content.test.js b/src/plugins/home/public/application/components/tutorial/content.test.js index e0b0a256f207c..f8a75d0a04f1c 100644 --- a/src/plugins/home/public/application/components/tutorial/content.test.js +++ b/src/plugins/home/public/application/components/tutorial/content.test.js @@ -11,12 +11,6 @@ import { shallow } from 'enzyme'; import { Content } from './content'; -jest.mock('../../../../../kibana_react/public', () => { - return { - Markdown: () => <div className="markdown" />, - }; -}); - test('should render content with markdown', () => { const component = shallow( <Content diff --git a/src/plugins/home/public/application/components/tutorial/footer.js b/src/plugins/home/public/application/components/tutorial/footer.js index 002ae02e4a1d2..56985dab3f692 100644 --- a/src/plugins/home/public/application/components/tutorial/footer.js +++ b/src/plugins/home/public/application/components/tutorial/footer.js @@ -9,34 +9,30 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiText, EuiButton } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiButton } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; export function Footer({ url, label }) { return ( - <div> - <EuiHorizontalRule /> + <EuiFlexGroup justifyContent="spaceBetween" alignItems="center"> + <EuiFlexItem grow={false}> + <EuiText> + <p> + <FormattedMessage + id="home.exploreYourDataDescription" + defaultMessage="When all steps are complete, you're ready to explore your data." + /> + </p> + </EuiText> + </EuiFlexItem> - <EuiFlexGroup justifyContent="spaceBetween" alignItems="center"> - <EuiFlexItem grow={false}> - <EuiText> - <p> - <FormattedMessage - id="home.exploreYourDataDescription" - defaultMessage="When all steps are complete, you're ready to explore your data." - /> - </p> - </EuiText> - </EuiFlexItem> - - <EuiFlexItem grow={false}> - <EuiButton fill href={url}> - {label} - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> - </div> + <EuiFlexItem grow={false}> + <EuiButton fill href={url}> + {label} + </EuiButton> + </EuiFlexItem> + </EuiFlexGroup> ); } diff --git a/src/plugins/home/public/application/components/tutorial/instruction.js b/src/plugins/home/public/application/components/tutorial/instruction.js index e4b3b3f321bf9..ebe78b78f300d 100644 --- a/src/plugins/home/public/application/components/tutorial/instruction.js +++ b/src/plugins/home/public/application/components/tutorial/instruction.js @@ -10,18 +10,7 @@ import React, { Suspense, useMemo } from 'react'; import PropTypes from 'prop-types'; import { Content } from './content'; -import { - EuiCodeBlock, - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, - EuiCopy, - EuiButton, - EuiLoadingSpinner, - EuiErrorBoundary, -} from '@elastic/eui'; - -import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCodeBlock, EuiSpacer, EuiLoadingSpinner, EuiErrorBoundary } from '@elastic/eui'; import { getServices } from '../../kibana_services'; @@ -39,16 +28,21 @@ export function Instruction({ let pre; if (textPre) { - pre = <Content text={replaceTemplateStrings(textPre)} />; + pre = ( + <> + <Content text={replaceTemplateStrings(textPre)} /> + <EuiSpacer size="m" /> + </> + ); } let post; if (textPost) { post = ( - <div> + <> <EuiSpacer size="m" /> <Content text={replaceTemplateStrings(textPost)} /> - </div> + </> ); } const customComponent = tutorialService.getCustomComponent(customComponentName); @@ -59,7 +53,6 @@ export function Instruction({ } }, [customComponent]); - let copyButton; let commandBlock; if (commands) { const cmdText = commands @@ -67,35 +60,16 @@ export function Instruction({ return replaceTemplateStrings(cmd, paramValues); }) .join('\n'); - copyButton = ( - <EuiCopy textToCopy={cmdText}> - {(copy) => ( - <EuiButton size="s" onClick={copy}> - <FormattedMessage - id="home.tutorial.instruction.copyButtonLabel" - defaultMessage="Copy snippet" - /> - </EuiButton> - )} - </EuiCopy> - ); commandBlock = ( - <div> - <EuiSpacer size="m" /> - <EuiCodeBlock language="bash">{cmdText}</EuiCodeBlock> - </div> + <EuiCodeBlock isCopyable language="bash"> + {cmdText} + </EuiCodeBlock> ); } return ( <div> - <EuiFlexGroup justifyContent="spaceBetween" alignItems="flexEnd"> - <EuiFlexItem grow={false}>{pre}</EuiFlexItem> - - <EuiFlexItem className="homTutorial__instruction" grow={false}> - {copyButton} - </EuiFlexItem> - </EuiFlexGroup> + {pre} {commandBlock} @@ -114,8 +88,6 @@ export function Instruction({ )} {post} - - <EuiSpacer /> </div> ); } diff --git a/src/plugins/home/public/application/components/tutorial/instruction_set.js b/src/plugins/home/public/application/components/tutorial/instruction_set.js index 08b55a527b3cf..822c60cdc31ba 100644 --- a/src/plugins/home/public/application/components/tutorial/instruction_set.js +++ b/src/plugins/home/public/application/components/tutorial/instruction_set.js @@ -21,12 +21,13 @@ import { EuiFlexItem, EuiButton, EuiCallOut, - EuiButtonEmpty, EuiTitle, + EuiSplitPanel, } from '@elastic/eui'; import * as StatusCheckStates from './status_check_states'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; +import { euiThemeVars } from '@kbn/ui-shared-deps-src/theme'; class InstructionSetUi extends React.Component { constructor(props) { @@ -97,7 +98,12 @@ class InstructionSetUi extends React.Component { color = 'warning'; break; } - return <EuiCallOut title={message} color={color} />; + return ( + <> + <EuiSpacer size="s" /> + <EuiCallOut title={message} color={color} /> + </> + ); } getStepStatus(statusCheckState) { @@ -131,27 +137,20 @@ class InstructionSetUi extends React.Component { const { statusCheckState, statusCheckConfig, onStatusCheck } = this.props; const checkStatusStep = ( <Fragment> - <EuiFlexGroup justifyContent="spaceBetween" alignItems="center"> - <EuiFlexItem> - <Content text={statusCheckConfig.text} /> - </EuiFlexItem> - - <EuiFlexItem grow={false}> - <EuiButton - onClick={onStatusCheck} - isLoading={statusCheckState === StatusCheckStates.FETCHING} - > - {statusCheckConfig.btnLabel || ( - <FormattedMessage - id="home.tutorial.instructionSet.checkStatusButtonLabel" - defaultMessage="Check status" - /> - )} - </EuiButton> - </EuiFlexItem> - </EuiFlexGroup> + <Content text={statusCheckConfig.text} /> <EuiSpacer size="s" /> + <EuiButton + onClick={onStatusCheck} + isLoading={statusCheckState === StatusCheckStates.FETCHING} + > + {statusCheckConfig.btnLabel || ( + <FormattedMessage + id="home.tutorial.instructionSet.checkStatusButtonLabel" + defaultMessage="Check status" + /> + )} + </EuiButton> {this.renderStatusCheckMessage()} </Fragment> @@ -202,27 +201,29 @@ class InstructionSetUi extends React.Component { steps.push(this.renderStatusCheck()); } - return <EuiSteps steps={steps} firstStepNumber={this.props.offset} />; + return ( + <> + <EuiSpacer /> + <EuiSteps titleSize="xs" steps={steps} firstStepNumber={this.props.offset} /> + </> + ); }; renderHeader = () => { let paramsVisibilityToggle; if (this.props.params) { - const ariaLabel = this.props.intl.formatMessage({ - id: 'home.tutorial.instructionSet.toggleAriaLabel', - defaultMessage: 'toggle command parameters visibility', - }); paramsVisibilityToggle = ( - <EuiButtonEmpty + <EuiButton + size="s" iconType={this.state.isParamFormVisible ? 'arrowDown' : 'arrowRight'} - aria-label={ariaLabel} + aria-pressed={this.state.isParamFormVisible} onClick={this.handleToggleVisibility} > <FormattedMessage id="home.tutorial.instructionSet.customizeLabel" defaultMessage="Customize your code snippets" /> - </EuiButtonEmpty> + </EuiButton> ); } @@ -245,11 +246,14 @@ class InstructionSetUi extends React.Component { } return ( - <EuiCallOut - title={this.props.callOut.title} - children={this.props.callOut.message} - iconType={this.props.callOut.iconType} - /> + <> + <EuiSpacer /> + <EuiCallOut + title={this.props.callOut.title} + children={this.props.callOut.message} + iconType={this.props.callOut.iconType} + /> + </> ); }; @@ -257,28 +261,29 @@ class InstructionSetUi extends React.Component { let paramsForm; if (this.props.params && this.state.isParamFormVisible) { paramsForm = ( - <ParameterForm - params={this.props.params} - paramValues={this.props.paramValues} - setParameter={this.props.setParameter} - /> + <> + <EuiSpacer /> + <ParameterForm + params={this.props.params} + paramValues={this.props.paramValues} + setParameter={this.props.setParameter} + /> + </> ); } return ( - <div> - {this.renderHeader()} - - {this.renderCallOut()} - - {paramsForm} - - <EuiTabs>{this.renderTabs()}</EuiTabs> - - <EuiSpacer size="m" /> - - {this.renderInstructions()} - </div> + <EuiSplitPanel.Outer> + <EuiSplitPanel.Inner color="subdued" paddingSize="none"> + <EuiTabs style={{ padding: `0 ${euiThemeVars.euiSizeL}` }}>{this.renderTabs()}</EuiTabs> + </EuiSplitPanel.Inner> + <EuiSplitPanel.Inner paddingSize="l"> + {this.renderHeader()} + {paramsForm} + {this.renderCallOut()} + {this.renderInstructions()} + </EuiSplitPanel.Inner> + </EuiSplitPanel.Outer> ); } } diff --git a/src/plugins/home/public/application/components/tutorial/instruction_set.test.js b/src/plugins/home/public/application/components/tutorial/instruction_set.test.js index 1bce4f72fde60..6faadf275bea3 100644 --- a/src/plugins/home/public/application/components/tutorial/instruction_set.test.js +++ b/src/plugins/home/public/application/components/tutorial/instruction_set.test.js @@ -34,12 +34,6 @@ const instructionVariants = [ }, ]; -jest.mock('../../../../../kibana_react/public', () => { - return { - Markdown: () => <div className="markdown" />, - }; -}); - test('render', () => { const component = shallowWithIntl( <InstructionSet.WrappedComponent diff --git a/src/plugins/home/public/application/components/tutorial/introduction.js b/src/plugins/home/public/application/components/tutorial/introduction.js index 11b381d3888f6..35fa646d7aeda 100644 --- a/src/plugins/home/public/application/components/tutorial/introduction.js +++ b/src/plugins/home/public/application/components/tutorial/introduction.js @@ -9,16 +9,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Content } from './content'; -import { - EuiTitle, - EuiFlexItem, - EuiFlexGroup, - EuiSpacer, - EuiImage, - EuiButton, - EuiIcon, - EuiBetaBadge, -} from '@elastic/eui'; +import { EuiImage, EuiLink, EuiBetaBadge, EuiPageHeader } from '@elastic/eui'; import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; @@ -30,13 +21,13 @@ function IntroductionUI({ iconType, isBeta, intl, + notices, }) { - let img; + let rightSideItems; if (previewUrl) { - img = ( + rightSideItems = [ <EuiImage size="l" - hasShadow allowFullScreen fullScreenIconColor="dark" alt={intl.formatMessage({ @@ -44,29 +35,21 @@ function IntroductionUI({ defaultMessage: 'screenshot of primary dashboard.', })} url={previewUrl} - /> - ); + />, + ]; } let exportedFields; if (exportedFieldsUrl) { exportedFields = ( - <div> - <EuiSpacer /> - <EuiButton href={exportedFieldsUrl} target="_blank" rel="noopener"> + <> + <br /> + <EuiLink href={exportedFieldsUrl} target="_blank" rel="noopener"> <FormattedMessage id="home.tutorial.introduction.viewButtonLabel" defaultMessage="View exported fields" /> - </EuiButton> - </div> - ); - } - let icon; - if (iconType) { - icon = ( - <EuiFlexItem grow={false}> - <EuiIcon size="xl" title="" type={iconType} /> - </EuiFlexItem> + </EuiLink> + </> ); } let betaBadge; @@ -81,31 +64,28 @@ function IntroductionUI({ ); } return ( - <EuiFlexGroup> - <EuiFlexItem> - <EuiFlexGroup gutterSize="l" alignItems="center"> - {icon} - <EuiFlexItem grow={false}> - <EuiTitle size="l"> - <h1> - {title} - {betaBadge && ( - <> - - {betaBadge} - </> - )} - </h1> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - - <Content text={description} /> - {exportedFields} - </EuiFlexItem> - - <EuiFlexItem grow={false}>{img}</EuiFlexItem> - </EuiFlexGroup> + <EuiPageHeader + iconType={iconType} + pageTitle={ + <> + {title} + {betaBadge && ( + <> + + {betaBadge} + </> + )} + </> + } + description={ + <> + <Content text={description} /> + {exportedFields} + {notices} + </> + } + rightSideItems={rightSideItems} + /> ); } @@ -116,6 +96,7 @@ IntroductionUI.propTypes = { exportedFieldsUrl: PropTypes.string, iconType: PropTypes.string, isBeta: PropTypes.bool, + notices: PropTypes.node, }; IntroductionUI.defaultProps = { diff --git a/src/plugins/home/public/application/components/tutorial/introduction.test.js b/src/plugins/home/public/application/components/tutorial/introduction.test.js index a0ab9d8c8e6a7..949f84d0181ed 100644 --- a/src/plugins/home/public/application/components/tutorial/introduction.test.js +++ b/src/plugins/home/public/application/components/tutorial/introduction.test.js @@ -11,12 +11,6 @@ import { shallowWithIntl } from '@kbn/test/jest'; import { Introduction } from './introduction'; -jest.mock('../../../../../kibana_react/public', () => { - return { - Markdown: () => <div className="markdown" />, - }; -}); - test('render', () => { const component = shallowWithIntl( <Introduction.WrappedComponent diff --git a/src/plugins/home/public/application/components/tutorial/saved_objects_installer.js b/src/plugins/home/public/application/components/tutorial/saved_objects_installer.js index a218630a193fd..56cc5814df96e 100644 --- a/src/plugins/home/public/application/components/tutorial/saved_objects_installer.js +++ b/src/plugins/home/public/application/components/tutorial/saved_objects_installer.js @@ -14,7 +14,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { - EuiSteps, + EuiTitle, EuiFlexGroup, EuiFlexItem, EuiText, @@ -160,15 +160,24 @@ Click 'Confirm overwrite' to import and overwrite existing objects. Any changes ); } - renderInstallStep = () => { + render() { const installMsg = this.props.installMsg ? this.props.installMsg : this.props.intl.formatMessage({ id: 'home.tutorial.savedObject.installLabel', defaultMessage: 'Imports index pattern, visualizations and pre-defined dashboards.', }); - const installStep = ( - <Fragment> + + return ( + <> + <EuiTitle size="m"> + <h2> + {this.props.intl.formatMessage({ + id: 'home.tutorial.savedObject.loadTitle', + defaultMessage: 'Load Kibana objects', + })} + </h2> + </EuiTitle> <EuiFlexGroup justifyContent="spaceBetween" alignItems="center"> <EuiFlexItem> <EuiText> @@ -190,22 +199,8 @@ Click 'Confirm overwrite' to import and overwrite existing objects. Any changes <EuiSpacer size="s" /> {this.renderInstallMessage()} - </Fragment> + </> ); - - return { - title: this.props.intl.formatMessage({ - id: 'home.tutorial.savedObject.loadTitle', - defaultMessage: 'Load Kibana objects', - }), - status: this.state.isInstalled ? 'complete' : 'incomplete', - children: installStep, - key: 'installStep', - }; - }; - - render() { - return <EuiSteps steps={[this.renderInstallStep()]} />; } } diff --git a/src/plugins/home/public/application/components/tutorial/tutorial.js b/src/plugins/home/public/application/components/tutorial/tutorial.js index 52daa53d4585c..508a236bf45d4 100644 --- a/src/plugins/home/public/application/components/tutorial/tutorial.js +++ b/src/plugins/home/public/application/components/tutorial/tutorial.js @@ -7,26 +7,18 @@ */ import _ from 'lodash'; -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Footer } from './footer'; import { Introduction } from './introduction'; import { InstructionSet } from './instruction_set'; import { SavedObjectsInstaller } from './saved_objects_installer'; -import { - EuiSpacer, - EuiPage, - EuiPanel, - EuiText, - EuiPageBody, - EuiButtonGroup, - EuiFlexGroup, - EuiFlexItem, -} from '@elastic/eui'; +import { EuiSpacer, EuiPanel, EuiButton, EuiButtonGroup, EuiFormRow } from '@elastic/eui'; import * as StatusCheckStates from './status_check_states'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { getServices } from '../../kibana_services'; +import { KibanaPageTemplate } from '../../../../../kibana_react/public'; const INSTRUCTIONS_TYPE = { ELASTIC_CLOUD: 'elasticCloud', @@ -250,19 +242,22 @@ class TutorialUi extends React.Component { }, ]; return ( - <EuiFlexGroup justifyContent="center"> - <EuiFlexItem grow={false}> + <> + <EuiSpacer /> + <EuiFormRow> <EuiButtonGroup + isFullWidth + buttonSize="m" options={radioButtons} idSelected={this.state.visibleInstructions} onChange={this.setVisibleInstructions} - color="primary" + color="text" legend={i18n.translate('home.tutorial.selectionLegend', { defaultMessage: 'Deployment type', })} /> - </EuiFlexItem> - </EuiFlexGroup> + </EuiFormRow> + </> ); } }; @@ -286,23 +281,25 @@ class TutorialUi extends React.Component { offset += instructionSet.instructionVariants[0].instructions.length; return ( - <InstructionSet - title={instructionSet.title} - callOut={instructionSet.callOut} - instructionVariants={instructionSet.instructionVariants} - statusCheckConfig={instructionSet.statusCheck} - statusCheckState={this.state.statusCheckStates[index]} - onStatusCheck={() => { - this.onStatusCheck(index); - }} - offset={currentOffset} - params={instructions.params} - paramValues={this.state.paramValues} - setParameter={this.setParameter} - replaceTemplateStrings={this.props.replaceTemplateStrings} - key={index} - isCloudEnabled={this.props.isCloudEnabled} - /> + <Fragment key={index}> + <InstructionSet + title={instructionSet.title} + callOut={instructionSet.callOut} + instructionVariants={instructionSet.instructionVariants} + statusCheckConfig={instructionSet.statusCheck} + statusCheckState={this.state.statusCheckStates[index]} + onStatusCheck={() => { + this.onStatusCheck(index); + }} + offset={currentOffset} + params={instructions.params} + paramValues={this.state.paramValues} + setParameter={this.setParameter} + replaceTemplateStrings={this.props.replaceTemplateStrings} + isCloudEnabled={this.props.isCloudEnabled} + /> + {index < instructions.instructionSets.length - 1 && <EuiSpacer />} + </Fragment> ); }); }; @@ -313,11 +310,16 @@ class TutorialUi extends React.Component { } return ( - <SavedObjectsInstaller - bulkCreate={this.props.bulkCreate} - savedObjects={this.state.tutorial.savedObjects} - installMsg={this.state.tutorial.savedObjectsInstallMsg} - /> + <> + <EuiSpacer /> + <EuiPanel paddingSize="l"> + <SavedObjectsInstaller + bulkCreate={this.props.bulkCreate} + savedObjects={this.state.tutorial.savedObjects} + installMsg={this.state.tutorial.savedObjectsInstallMsg} + /> + </EuiPanel> + </> ); }; @@ -338,22 +340,23 @@ class TutorialUi extends React.Component { } if (url && label) { - return <Footer label={label} url={url} />; + return ( + <> + <EuiSpacer /> + <EuiPanel paddingSize="l"> + <Footer label={label} url={url} /> + </EuiPanel> + </> + ); } }; renderModuleNotices() { const notices = getServices().tutorialService.getModuleNotices(); if (notices.length && this.state.tutorial.moduleName) { - return ( - <EuiFlexGroup direction="column" gutterSize="none"> - {notices.map((ModuleNotice, index) => ( - <EuiFlexItem key={index}> - <ModuleNotice moduleName={this.state.tutorial.moduleName} /> - </EuiFlexItem> - ))} - </EuiFlexGroup> - ); + return notices.map((ModuleNotice, index) => ( + <ModuleNotice key={index} moduleName={this.state.tutorial.moduleName} /> + )); } else { return null; } @@ -363,17 +366,34 @@ class TutorialUi extends React.Component { let content; if (this.state.notFound) { content = ( - <div className="homTutorial__notFoundPanel"> - <EuiText> - <p> + <KibanaPageTemplate + isEmptyState={true} + pageHeader={{ + iconType: 'faceSad', + iconProps: { + color: 'subdued', + }, + pageTitle: ( <FormattedMessage id="home.tutorial.noTutorialLabel" defaultMessage="Unable to find tutorial {tutorialId}" values={{ tutorialId: this.props.tutorialId }} /> - </p> - </EuiText> - </div> + ), + rightSideItems: [ + <EuiButton + href={this.props.addBasePath('/app/home#/tutorial_directory')} + fill + iconType="sortLeft" + iconSide="left" + > + {i18n.translate('home.tutorial.backToDirectory', { + defaultMessage: 'Back to directory', + })} + </EuiButton>, + ], + }} + /> ); } @@ -405,27 +425,20 @@ class TutorialUi extends React.Component { exportedFieldsUrl={exportedFieldsUrl} iconType={icon} isBeta={this.state.tutorial.isBeta} + notices={this.renderModuleNotices()} /> - {this.renderModuleNotices()} - <EuiSpacer /> - <div className="eui-textCenter">{this.renderInstructionSetsToggle()}</div> + {this.renderInstructionSetsToggle()} <EuiSpacer /> - <EuiPanel paddingSize="l"> - {this.renderInstructionSets(instructions)} - {this.renderSavedObjectsInstaller()} - {this.renderFooter()} - </EuiPanel> + {this.renderInstructionSets(instructions)} + {this.renderSavedObjectsInstaller()} + {this.renderFooter()} </div> ); } - return ( - <EuiPage restrictWidth={1200}> - <EuiPageBody>{content}</EuiPageBody> - </EuiPage> - ); + return <KibanaPageTemplate template="empty">{content}</KibanaPageTemplate>; } } diff --git a/src/plugins/home/public/application/components/tutorial/tutorial.test.js b/src/plugins/home/public/application/components/tutorial/tutorial.test.js index c76b20e63ae95..c68f5ec69e161 100644 --- a/src/plugins/home/public/application/components/tutorial/tutorial.test.js +++ b/src/plugins/home/public/application/components/tutorial/tutorial.test.js @@ -33,11 +33,6 @@ jest.mock('../../kibana_services', () => ({ }, }), })); -jest.mock('../../../../../kibana_react/public', () => { - return { - Markdown: () => <div className="markdown" />, - }; -}); function buildInstructionSet(type) { return { diff --git a/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts b/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts index dd035a66c5ced..cf0c27ed9be73 100644 --- a/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts +++ b/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts @@ -53,6 +53,6 @@ export function cloudwatchLogsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions([], context), elasticCloud: cloudInstructions(), onPremElasticCloud: onPremCloudInstructions(), - integrationBrowserCategories: ['security', 'network', 'web'], + integrationBrowserCategories: ['aws', 'cloud', 'datastore', 'security', 'network'], }; } diff --git a/src/plugins/index_pattern_field_editor/__jest__/client_integration/helpers/jest.mocks.tsx b/src/plugins/index_pattern_field_editor/__jest__/client_integration/helpers/jest.mocks.tsx index e291ec7b4ca08..d33a0d2a87fb5 100644 --- a/src/plugins/index_pattern_field_editor/__jest__/client_integration/helpers/jest.mocks.tsx +++ b/src/plugins/index_pattern_field_editor/__jest__/client_integration/helpers/jest.mocks.tsx @@ -9,12 +9,6 @@ import React from 'react'; const EDITOR_ID = 'testEditor'; -jest.mock('@elastic/eui/lib/services/accessibility', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/__snapshots__/color.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/__snapshots__/color.test.tsx.snap index 7406e5ae9bb2d..1cff82729e6f9 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/__snapshots__/color.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/__snapshots__/color.test.tsx.snap @@ -76,7 +76,12 @@ exports[`ColorFormatEditor should render multiple colors 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> @@ -170,7 +175,12 @@ exports[`ColorFormatEditor should render other type normally (range field) 1`] = }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> @@ -264,7 +274,12 @@ exports[`ColorFormatEditor should render string type normally (regex field) 1`] }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.tsx.snap index 664912789b0e3..3b476a6037aed 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.tsx.snap @@ -55,7 +55,12 @@ exports[`StaticLookupFormatEditor should render multiple lookup entries and unkn }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} style={ Object { @@ -159,7 +164,12 @@ exports[`StaticLookupFormatEditor should render normally 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} style={ Object { diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap index 79c1a11cfef84..3890d6c2b9ddb 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap @@ -292,7 +292,7 @@ exports[`UrlFormatEditor should render normally 1`] = ` </div> <table class="euiTable euiTable--compressed euiTable--responsive" - id="generated-id" + id="__table_generated-id" tabindex="-1" > <caption diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.test.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.test.tsx index 48d3a5dfea7c6..6394d42b691f1 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.test.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.test.tsx @@ -15,12 +15,6 @@ import { createKibanaReactContext } from '../../../../../../kibana_react/public' import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -jest.mock('@elastic/eui/lib/services/accessibility', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - const fieldType = 'string'; const format = { getConverterFor: jest diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap index 1a0b96c14fe35..71693a1e5cb8c 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap @@ -52,7 +52,12 @@ exports[`FormatEditorSamples should render normally 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap index 933948411cc72..b9d1b3992778f 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap @@ -172,11 +172,13 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` isInvalid={true} label="Script" > - <eui-code-editor + <code-editor + aria-label="Script editor" data-test-subj="editorFieldScript" height="300px" - mode="groovy" + languageId="painless" onChange={[Function]} + value="" width="100%" /> </eui-form-row> @@ -407,10 +409,11 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` isInvalid={false} label="Script" > - <eui-code-editor + <code-editor + aria-label="Script editor" data-test-subj="editorFieldScript" height="300px" - mode="groovy" + languageId="painless" onChange={[Function]} value="doc.test.value" width="100%" @@ -705,11 +708,13 @@ exports[`FieldEditor should show conflict field warning 1`] = ` isInvalid={true} label="Script" > - <eui-code-editor + <code-editor + aria-label="Script editor" data-test-subj="editorFieldScript" height="300px" - mode="groovy" + languageId="painless" onChange={[Function]} + value="" width="100%" /> </eui-form-row> @@ -1033,10 +1038,11 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` isInvalid={false} label="Script" > - <eui-code-editor + <code-editor + aria-label="Script editor" data-test-subj="editorFieldScript" height="300px" - mode="groovy" + languageId="painless" onChange={[Function]} value="doc.test.value" width="100%" @@ -1387,11 +1393,13 @@ exports[`FieldEditor should show multiple type field warning with a table contai isInvalid={true} label="Script" > - <eui-code-editor + <code-editor + aria-label="Script editor" data-test-subj="editorFieldScript" height="300px" - mode="groovy" + languageId="painless" onChange={[Function]} + value="" width="100%" /> </eui-form-row> diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx index 584662acbe62f..46255c72c6a99 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx @@ -10,8 +10,6 @@ import { IndexPattern, IndexPatternField, IndexPatternsService } from 'src/plugi import { FieldFormatInstanceType } from 'src/plugins/field_formats/common'; import { findTestSubject } from '@elastic/eui/lib/test'; -jest.mock('brace/mode/groovy', () => ({})); - import { FieldEditor, FieldEdiorProps } from './field_editor'; import { mockManagementPlugin } from '../../mocks'; @@ -23,7 +21,6 @@ jest.mock('@elastic/eui', () => ({ EuiButtonEmpty: 'eui-button-empty', EuiCallOut: 'eui-call-out', EuiCode: 'eui-code', - EuiCodeEditor: 'eui-code-editor', EuiConfirmModal: 'eui-confirm-modal', EuiFieldNumber: 'eui-field-number', EuiFieldText: 'eui-field-text', @@ -42,6 +39,15 @@ jest.mock('@elastic/eui', () => ({ euiPaletteColorBlind: () => ['red'], })); +jest.mock('../../../../kibana_react/public', () => { + const original = jest.requireActual('../../../../kibana_react/public'); + + return { + ...original, + CodeEditor: `code-editor`, + }; +}); + jest.mock('../../scripting_languages', () => ({ getEnabledScriptingLanguages: () => ['painless', 'testlang'], getSupportedScriptingLanguages: () => ['painless'], diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx index bdc18938f9d6c..695d02d0744fb 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx @@ -15,7 +15,6 @@ import { EuiButtonEmpty, EuiCallOut, EuiCode, - EuiCodeEditor, EuiConfirmModal, EuiFieldNumber, EuiFieldText, @@ -33,6 +32,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { PainlessLang } from '@kbn/monaco'; import type { FieldFormatInstanceType } from 'src/plugins/field_formats/common'; import { getEnabledScriptingLanguages, @@ -46,7 +46,7 @@ import { ES_FIELD_TYPES, DataPublicPluginStart, } from '../../../../../plugins/data/public'; -import { context as contextType } from '../../../../kibana_react/public'; +import { context as contextType, CodeEditor } from '../../../../kibana_react/public'; import { ScriptingDisabledCallOut, ScriptingWarningCallOut, @@ -59,9 +59,6 @@ import { IndexPatternManagmentContextValue } from '../../types'; import { FIELD_TYPES_BY_LANG, DEFAULT_FIELD_TYPES } from './constants'; import { executeScript, isScriptValid } from './lib'; -// This loads Ace editor's "groovy" mode, used below to highlight the script. -import 'brace/mode/groovy'; - const getFieldTypeFormatsList = ( field: IndexPatternField['spec'], defaultFieldFormat: FieldFormatInstanceType, @@ -594,13 +591,16 @@ export class FieldEditor extends PureComponent<FieldEdiorProps, FieldEditorState isInvalid={isInvalid} error={isInvalid ? errorMsg : null} > - <EuiCodeEditor - value={spec.script} - data-test-subj="editorFieldScript" - onChange={this.onScriptChange} - mode="groovy" + <CodeEditor + languageId={PainlessLang.ID} width="100%" height="300px" + value={spec.script ?? ''} + onChange={this.onScriptChange} + data-test-subj="editorFieldScript" + aria-label={i18n.translate('indexPatternManagement.scriptLabelAriaLabel', { + defaultMessage: 'Script editor', + })} /> </EuiFormRow> diff --git a/src/plugins/maps_ems/common/index.ts b/src/plugins/maps_ems/common/index.ts index f7d7ff1102e59..26fdb4fa795fe 100644 --- a/src/plugins/maps_ems/common/index.ts +++ b/src/plugins/maps_ems/common/index.ts @@ -10,7 +10,7 @@ export const TMS_IN_YML_ID = 'TMS in config/kibana.yml'; export const DEFAULT_EMS_FILE_API_URL = 'https://vector.maps.elastic.co'; export const DEFAULT_EMS_TILE_API_URL = 'https://tiles.maps.elastic.co'; -export const DEFAULT_EMS_LANDING_PAGE_URL = 'https://maps.elastic.co/v7.15'; +export const DEFAULT_EMS_LANDING_PAGE_URL = 'https://maps.elastic.co/v7.16'; export const DEFAULT_EMS_FONT_LIBRARY_URL = 'https://tiles.maps.elastic.co/fonts/{fontstack}/{range}.pbf'; diff --git a/src/plugins/presentation_util/public/components/controls/__stories__/controls_service_stub.ts b/src/plugins/presentation_util/public/components/controls/__stories__/controls_service_stub.ts index 59e7a44a83a17..faaa155249949 100644 --- a/src/plugins/presentation_util/public/components/controls/__stories__/controls_service_stub.ts +++ b/src/plugins/presentation_util/public/components/controls/__stories__/controls_service_stub.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { InputControlFactory } from '../types'; import { ControlsService } from '../controls_service'; +import { InputControlFactory } from '../../../services/controls'; import { flightFields, getEuiSelectableOptions } from './flights'; import { OptionsListEmbeddableFactory } from '../control_types/options_list'; diff --git a/src/plugins/presentation_util/public/components/controls/__stories__/input_controls.stories.tsx b/src/plugins/presentation_util/public/components/controls/__stories__/input_controls.stories.tsx index 2a463fece18da..66f1d8b36399e 100644 --- a/src/plugins/presentation_util/public/components/controls/__stories__/input_controls.stories.tsx +++ b/src/plugins/presentation_util/public/components/controls/__stories__/input_controls.stories.tsx @@ -10,9 +10,14 @@ import React, { useEffect, useMemo } from 'react'; import uuid from 'uuid'; import { decorators } from './decorators'; -import { providers } from '../../../services/storybook'; -import { getControlsServiceStub } from './controls_service_stub'; -import { ControlGroupContainerFactory } from '../control_group/control_group_container_factory'; +import { pluginServices, registry } from '../../../services/storybook'; +import { populateStorybookControlFactories } from './storybook_control_factories'; +import { ControlGroupContainerFactory } from '../control_group/embeddable/control_group_container_factory'; +import { ControlsPanels } from '../control_group/types'; +import { + OptionsListEmbeddableInput, + OPTIONS_LIST_CONTROL, +} from '../control_types/options_list/options_list_embeddable'; export default { title: 'Controls', @@ -20,17 +25,15 @@ export default { decorators, }; -const ControlGroupStoryComponent = () => { +const EmptyControlGroupStoryComponent = ({ panels }: { panels?: ControlsPanels }) => { const embeddableRoot: React.RefObject<HTMLDivElement> = useMemo(() => React.createRef(), []); - providers.overlays.start({}); - const overlays = providers.overlays.getService(); - - const controlsServiceStub = getControlsServiceStub(); + pluginServices.setRegistry(registry.start({})); + populateStorybookControlFactories(pluginServices.getServices().controls); useEffect(() => { (async () => { - const factory = new ControlGroupContainerFactory(controlsServiceStub, overlays); + const factory = new ControlGroupContainerFactory(); const controlGroupContainerEmbeddable = await factory.create({ inheritParentState: { useQuery: false, @@ -38,16 +41,57 @@ const ControlGroupStoryComponent = () => { useTimerange: false, }, controlStyle: 'oneLine', + panels: panels ?? {}, id: uuid.v4(), - panels: {}, }); if (controlGroupContainerEmbeddable && embeddableRoot.current) { controlGroupContainerEmbeddable.render(embeddableRoot.current); } })(); - }, [embeddableRoot, controlsServiceStub, overlays]); + }, [embeddableRoot, panels]); return <div ref={embeddableRoot} />; }; -export const ControlGroupStory = () => <ControlGroupStoryComponent />; +export const EmptyControlGroupStory = () => <EmptyControlGroupStoryComponent />; +export const ConfiguredControlGroupStory = () => ( + <EmptyControlGroupStoryComponent + panels={{ + optionsList1: { + type: OPTIONS_LIST_CONTROL, + order: 1, + width: 'auto', + explicitInput: { + title: 'Origin City', + id: 'optionsList1', + indexPattern: 'demo data flights', + field: 'OriginCityName', + defaultSelections: ['Toronto'], + } as OptionsListEmbeddableInput, + }, + optionsList2: { + type: OPTIONS_LIST_CONTROL, + order: 2, + width: 'auto', + explicitInput: { + title: 'Destination City', + id: 'optionsList2', + indexPattern: 'demo data flights', + field: 'DestCityName', + defaultSelections: ['London'], + } as OptionsListEmbeddableInput, + }, + optionsList3: { + type: OPTIONS_LIST_CONTROL, + order: 3, + width: 'auto', + explicitInput: { + title: 'Carrier', + id: 'optionsList3', + indexPattern: 'demo data flights', + field: 'Carrier', + } as OptionsListEmbeddableInput, + }, + }} + /> +); diff --git a/src/plugins/presentation_util/public/components/controls/__stories__/storybook_control_factories.ts b/src/plugins/presentation_util/public/components/controls/__stories__/storybook_control_factories.ts new file mode 100644 index 0000000000000..3048adc74d8c7 --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/__stories__/storybook_control_factories.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { flightFields, getEuiSelectableOptions } from './flights'; +import { OptionsListEmbeddableFactory } from '../control_types/options_list'; +import { InputControlFactory, PresentationControlsService } from '../../../services/controls'; + +export const populateStorybookControlFactories = ( + controlsServiceStub: PresentationControlsService +) => { + const optionsListFactoryStub = new OptionsListEmbeddableFactory( + ({ field, search }) => + new Promise((r) => setTimeout(() => r(getEuiSelectableOptions(field, search)), 500)), + () => Promise.resolve(['demo data flights']), + () => Promise.resolve(flightFields) + ); + + // cast to unknown because the stub cannot use the embeddable start contract to transform the EmbeddableFactoryDefinition into an EmbeddableFactory + const optionsListControlFactory = optionsListFactoryStub as unknown as InputControlFactory; + optionsListControlFactory.getDefaultInput = () => ({}); + controlsServiceStub.registerInputControlType(optionsListControlFactory); +}; diff --git a/src/plugins/presentation_util/public/components/controls/control_frame/control_frame_strings.ts b/src/plugins/presentation_util/public/components/controls/control_frame/control_frame_strings.ts deleted file mode 100644 index 5f9e89aa797cb..0000000000000 --- a/src/plugins/presentation_util/public/components/controls/control_frame/control_frame_strings.ts +++ /dev/null @@ -1,22 +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 { i18n } from '@kbn/i18n'; - -export const ControlFrameStrings = { - floatingActions: { - getEditButtonTitle: () => - i18n.translate('presentationUtil.inputControls.controlGroup.floatingActions.editTitle', { - defaultMessage: 'Manage control', - }), - getRemoveButtonTitle: () => - i18n.translate('presentationUtil.inputControls.controlGroup.floatingActions.removeTitle', { - defaultMessage: 'Remove control', - }), - }, -}; diff --git a/src/plugins/presentation_util/public/components/controls/control_frame/control_frame_component.tsx b/src/plugins/presentation_util/public/components/controls/control_group/component/control_frame_component.tsx similarity index 71% rename from src/plugins/presentation_util/public/components/controls/control_frame/control_frame_component.tsx rename to src/plugins/presentation_util/public/components/controls/control_group/component/control_frame_component.tsx index 240beea13b0e2..103ce6dd0e27c 100644 --- a/src/plugins/presentation_util/public/components/controls/control_frame/control_frame_component.tsx +++ b/src/plugins/presentation_util/public/components/controls/control_group/component/control_frame_component.tsx @@ -15,32 +15,28 @@ import { EuiFormRow, EuiToolTip, } from '@elastic/eui'; -import { ControlGroupContainer } from '../control_group/control_group_container'; -import { useChildEmbeddable } from '../hooks/use_child_embeddable'; -import { ControlStyle } from '../types'; -import { ControlFrameStrings } from './control_frame_strings'; + +import { ControlGroupInput } from '../types'; +import { EditControlButton } from '../editor/edit_control'; +import { useChildEmbeddable } from '../../hooks/use_child_embeddable'; +import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context'; +import { ControlGroupStrings } from '../control_group_strings'; export interface ControlFrameProps { - container: ControlGroupContainer; customPrepend?: JSX.Element; - controlStyle: ControlStyle; enableActions?: boolean; - onRemove?: () => void; embeddableId: string; - onEdit?: () => void; } -export const ControlFrame = ({ - customPrepend, - enableActions, - embeddableId, - controlStyle, - container, - onRemove, - onEdit, -}: ControlFrameProps) => { +export const ControlFrame = ({ customPrepend, enableActions, embeddableId }: ControlFrameProps) => { const embeddableRoot: React.RefObject<HTMLDivElement> = useMemo(() => React.createRef(), []); - const embeddable = useChildEmbeddable({ container, embeddableId }); + const { + useEmbeddableSelector, + containerActions: { untilEmbeddableLoaded, removeEmbeddable }, + } = useReduxContainerContext<ControlGroupInput>(); + const { controlStyle } = useEmbeddableSelector((state) => state); + + const embeddable = useChildEmbeddable({ untilEmbeddableLoaded, embeddableId }); const [title, setTitle] = useState<string>(); @@ -61,18 +57,13 @@ export const ControlFrame = ({ 'controlFrame--floatingActions-oneLine': !usingTwoLineLayout, })} > - <EuiToolTip content={ControlFrameStrings.floatingActions.getEditButtonTitle()}> - <EuiButtonIcon - aria-label={ControlFrameStrings.floatingActions.getEditButtonTitle()} - iconType="pencil" - onClick={onEdit} - color="text" - /> + <EuiToolTip content={ControlGroupStrings.floatingActions.getEditButtonTitle()}> + <EditControlButton embeddableId={embeddableId} /> </EuiToolTip> - <EuiToolTip content={ControlFrameStrings.floatingActions.getRemoveButtonTitle()}> + <EuiToolTip content={ControlGroupStrings.floatingActions.getRemoveButtonTitle()}> <EuiButtonIcon - aria-label={ControlFrameStrings.floatingActions.getRemoveButtonTitle()} - onClick={onRemove} + aria-label={ControlGroupStrings.floatingActions.getRemoveButtonTitle()} + onClick={() => removeEmbeddable(embeddableId)} iconType="cross" color="danger" /> diff --git a/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_component.tsx b/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_component.tsx index d683c0749d98d..4d5e8bc270e23 100644 --- a/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_component.tsx +++ b/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_component.tsx @@ -9,7 +9,7 @@ import '../control_group.scss'; import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import classNames from 'classnames'; import { arrayMove, @@ -29,46 +29,51 @@ import { LayoutMeasuringStrategy, } from '@dnd-kit/core'; +import { ControlGroupInput } from '../types'; +import { pluginServices } from '../../../../services'; import { ControlGroupStrings } from '../control_group_strings'; -import { ControlGroupContainer } from '../control_group_container'; +import { CreateControlButton } from '../editor/create_control'; +import { EditControlGroup } from '../editor/edit_control_group'; +import { forwardAllContext } from '../editor/forward_all_context'; import { ControlClone, SortableControl } from './control_group_sortable_item'; -import { OPTIONS_LIST_CONTROL } from '../../control_types/options_list/options_list_embeddable'; +import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context'; +import { controlGroupReducers } from '../state/control_group_reducers'; -interface ControlGroupProps { - controlGroupContainer: ControlGroupContainer; -} +export const ControlGroup = () => { + // Presentation Services Context + const { overlays } = pluginServices.getHooks(); + const { openFlyout } = overlays.useService(); -export const ControlGroup = ({ controlGroupContainer }: ControlGroupProps) => { - const [controlIds, setControlIds] = useState<string[]>([]); + // Redux embeddable container Context + const reduxContainerContext = useReduxContainerContext< + ControlGroupInput, + typeof controlGroupReducers + >(); + const { + useEmbeddableSelector, + useEmbeddableDispatch, + actions: { setControlOrders }, + } = reduxContainerContext; + const dispatch = useEmbeddableDispatch(); - // sync controlIds every time input panels change - useEffect(() => { - const subscription = controlGroupContainer.getInput$().subscribe(() => { - setControlIds((currentIds) => { - // sync control Ids with panels from container input. - const { panels } = controlGroupContainer.getInput(); - const newIds: string[] = []; - const allIds = [...currentIds, ...Object.keys(panels)]; - allIds.forEach((id) => { - const currentIndex = currentIds.indexOf(id); - if (!panels[id] && currentIndex !== -1) { - currentIds.splice(currentIndex, 1); - } - if (currentIndex === -1 && Boolean(panels[id])) { - newIds.push(id); - } - }); - return [...currentIds, ...newIds]; - }); - }); - return () => subscription.unsubscribe(); - }, [controlGroupContainer]); + // current state + const { panels } = useEmbeddableSelector((state) => state); - const [draggingId, setDraggingId] = useState<string | null>(null); + const idsInOrder = useMemo( + () => + Object.values(panels) + .sort((a, b) => (a.order > b.order ? 1 : -1)) + .reduce((acc, panel) => { + acc.push(panel.explicitInput.id); + return acc; + }, [] as string[]), + [panels] + ); + const [draggingId, setDraggingId] = useState<string | null>(null); const draggingIndex = useMemo( - () => (draggingId ? controlIds.indexOf(draggingId) : -1), - [controlIds, draggingId] + () => (draggingId ? idsInOrder.indexOf(draggingId) : -1), + [idsInOrder, draggingId] ); const sensors = useSensors( @@ -78,10 +83,10 @@ export const ControlGroup = ({ controlGroupContainer }: ControlGroupProps) => { const onDragEnd = ({ over }: DragEndEvent) => { if (over) { - const overIndex = controlIds.indexOf(over.id); + const overIndex = idsInOrder.indexOf(over.id); if (draggingIndex !== overIndex) { const newIndex = overIndex; - setControlIds((currentControlIds) => arrayMove(currentControlIds, draggingIndex, newIndex)); + dispatch(setControlOrders({ ids: arrayMove([...idsInOrder], draggingIndex, newIndex) })); } } setDraggingId(null); @@ -100,36 +105,26 @@ export const ControlGroup = ({ controlGroupContainer }: ControlGroupProps) => { strategy: LayoutMeasuringStrategy.Always, }} > - <SortableContext items={controlIds} strategy={rectSortingStrategy}> + <SortableContext items={idsInOrder} strategy={rectSortingStrategy}> <EuiFlexGroup className={classNames('controlGroup', { 'controlGroup-isDragging': draggingId })} alignItems="center" gutterSize={'m'} wrap={true} > - {controlIds.map((controlId, index) => ( - <SortableControl - onEdit={() => controlGroupContainer.editControl(controlId)} - onRemove={() => controlGroupContainer.removeEmbeddable(controlId)} - dragInfo={{ index, draggingIndex }} - container={controlGroupContainer} - controlStyle={controlGroupContainer.getInput().controlStyle} - embeddableId={controlId} - width={controlGroupContainer.getInput().panels[controlId].width} - key={controlId} - /> - ))} + {idsInOrder.map( + (controlId, index) => + panels[controlId] && ( + <SortableControl + dragInfo={{ index, draggingIndex }} + embeddableId={controlId} + key={controlId} + /> + ) + )} </EuiFlexGroup> </SortableContext> - <DragOverlay> - {draggingId ? ( - <ControlClone - width={controlGroupContainer.getInput().panels[draggingId].width} - embeddableId={draggingId} - container={controlGroupContainer} - /> - ) : null} - </DragOverlay> + <DragOverlay>{draggingId ? <ControlClone draggingId={draggingId} /> : null}</DragOverlay> </DndContext> </EuiFlexItem> <EuiFlexItem grow={false}> @@ -141,19 +136,15 @@ export const ControlGroup = ({ controlGroupContainer }: ControlGroupProps) => { iconType="gear" color="text" data-test-subj="inputControlsSortingButton" - onClick={controlGroupContainer.editControlGroup} + onClick={() => + openFlyout(forwardAllContext(<EditControlGroup />, reduxContainerContext)) + } /> </EuiToolTip> </EuiFlexItem> <EuiFlexItem> <EuiToolTip content={ControlGroupStrings.management.getAddControlTitle()}> - <EuiButtonIcon - aria-label={ControlGroupStrings.management.getManageButtonTitle()} - iconType="plus" - color="text" - data-test-subj="inputControlsSortingButton" - onClick={() => controlGroupContainer.createNewControl(OPTIONS_LIST_CONTROL)} // use popover when there are multiple types of control - /> + <CreateControlButton /> </EuiToolTip> </EuiFlexItem> </EuiFlexGroup> diff --git a/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_sortable_item.tsx b/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_sortable_item.tsx index 3ae171a588da4..5c222e3c130b5 100644 --- a/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_sortable_item.tsx +++ b/src/plugins/presentation_util/public/components/controls/control_group/component/control_group_sortable_item.tsx @@ -12,10 +12,9 @@ import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import classNames from 'classnames'; -import { ControlWidth } from '../../types'; -import { ControlGroupContainer } from '../control_group_container'; -import { useChildEmbeddable } from '../../hooks/use_child_embeddable'; -import { ControlFrame, ControlFrameProps } from '../../control_frame/control_frame_component'; +import { ControlGroupInput } from '../types'; +import { ControlFrame, ControlFrameProps } from './control_frame_component'; +import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context'; interface DragInfo { isOver?: boolean; @@ -26,7 +25,6 @@ interface DragInfo { export type SortableControlProps = ControlFrameProps & { dragInfo: DragInfo; - width: ControlWidth; }; /** @@ -60,91 +58,67 @@ export const SortableControl = (frameProps: SortableControlProps) => { const SortableControlInner = forwardRef< HTMLButtonElement, SortableControlProps & { style: HTMLAttributes<HTMLButtonElement>['style'] } ->( - ( - { - embeddableId, - controlStyle, - container, - dragInfo, - onRemove, - onEdit, - style, - width, - ...dragHandleProps - }, - dragHandleRef - ) => { - const { isOver, isDragging, draggingIndex, index } = dragInfo; +>(({ embeddableId, dragInfo, style, ...dragHandleProps }, dragHandleRef) => { + const { isOver, isDragging, draggingIndex, index } = dragInfo; + const { useEmbeddableSelector } = useReduxContainerContext<ControlGroupInput>(); + const { panels } = useEmbeddableSelector((state) => state); - const dragHandle = ( - <button ref={dragHandleRef} {...dragHandleProps} className="controlFrame--dragHandle"> - <EuiIcon type="grabHorizontal" /> - </button> - ); + const width = panels[embeddableId].width; - return ( - <EuiFlexItem - grow={width === 'auto'} - className={classNames('controlFrame--wrapper', { - 'controlFrame--wrapper-isDragging': isDragging, - 'controlFrame--wrapper-small': width === 'small', - 'controlFrame--wrapper-medium': width === 'medium', - 'controlFrame--wrapper-large': width === 'large', - 'controlFrame--wrapper-insertBefore': isOver && (index ?? -1) < (draggingIndex ?? -1), - 'controlFrame--wrapper-insertAfter': isOver && (index ?? -1) > (draggingIndex ?? -1), - })} - style={style} - > - <ControlFrame - enableActions={draggingIndex === -1} - controlStyle={controlStyle} - embeddableId={embeddableId} - customPrepend={dragHandle} - container={container} - onRemove={onRemove} - onEdit={onEdit} - /> - </EuiFlexItem> - ); - } -); + const dragHandle = ( + <button ref={dragHandleRef} {...dragHandleProps} className="controlFrame--dragHandle"> + <EuiIcon type="grabHorizontal" /> + </button> + ); + + return ( + <EuiFlexItem + grow={width === 'auto'} + className={classNames('controlFrame--wrapper', { + 'controlFrame--wrapper-isDragging': isDragging, + 'controlFrame--wrapper-small': width === 'small', + 'controlFrame--wrapper-medium': width === 'medium', + 'controlFrame--wrapper-large': width === 'large', + 'controlFrame--wrapper-insertBefore': isOver && (index ?? -1) < (draggingIndex ?? -1), + 'controlFrame--wrapper-insertAfter': isOver && (index ?? -1) > (draggingIndex ?? -1), + })} + style={style} + > + <ControlFrame + enableActions={draggingIndex === -1} + embeddableId={embeddableId} + customPrepend={dragHandle} + /> + </EuiFlexItem> + ); +}); /** * A simplified clone version of the control which is dragged. This version only shows * the title, because individual controls can be any size, and dragging a wide item * can be quite cumbersome. */ -export const ControlClone = ({ - embeddableId, - container, - width, -}: { - embeddableId: string; - container: ControlGroupContainer; - width: ControlWidth; -}) => { - const embeddable = useChildEmbeddable({ embeddableId, container }); - const layout = container.getInput().controlStyle; +export const ControlClone = ({ draggingId }: { draggingId: string }) => { + const { useEmbeddableSelector } = useReduxContainerContext<ControlGroupInput>(); + const { panels, controlStyle } = useEmbeddableSelector((state) => state); + + const width = panels[draggingId].width; + const title = panels[draggingId].explicitInput.title; return ( <EuiFlexItem className={classNames('controlFrame--cloneWrapper', { 'controlFrame--cloneWrapper-small': width === 'small', 'controlFrame--cloneWrapper-medium': width === 'medium', 'controlFrame--cloneWrapper-large': width === 'large', - 'controlFrame--cloneWrapper-twoLine': layout === 'twoLine', + 'controlFrame--cloneWrapper-twoLine': controlStyle === 'twoLine', })} > - {layout === 'twoLine' ? ( - <EuiFormLabel>{embeddable?.getInput().title}</EuiFormLabel> - ) : undefined} + {controlStyle === 'twoLine' ? <EuiFormLabel>{title}</EuiFormLabel> : undefined} <EuiFlexGroup gutterSize="none" className={'controlFrame--draggable'}> <EuiFlexItem grow={false}> <EuiIcon type="grabHorizontal" className="controlFrame--dragHandle" /> </EuiFlexItem> - {container.getInput().controlStyle === 'oneLine' ? ( - <EuiFlexItem>{embeddable?.getInput().title}</EuiFlexItem> - ) : undefined} + {controlStyle === 'oneLine' ? <EuiFlexItem>{title}</EuiFlexItem> : undefined} </EuiFlexGroup> </EuiFlexItem> ); diff --git a/src/plugins/presentation_util/public/components/controls/control_group/control_group_container.tsx b/src/plugins/presentation_util/public/components/controls/control_group/control_group_container.tsx deleted file mode 100644 index 03249889dfdea..0000000000000 --- a/src/plugins/presentation_util/public/components/controls/control_group/control_group_container.tsx +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import ReactDOM from 'react-dom'; -import { cloneDeep } from 'lodash'; - -import { - Container, - EmbeddableFactory, - EmbeddableFactoryNotFoundError, -} from '../../../../../embeddable/public'; -import { - InputControlEmbeddable, - InputControlInput, - InputControlOutput, - IEditableControlFactory, - ControlWidth, -} from '../types'; -import { ControlsService } from '../controls_service'; -import { ControlGroupInput, ControlPanelState } from './types'; -import { ManageControlComponent } from './editor/manage_control'; -import { toMountPoint } from '../../../../../kibana_react/public'; -import { ControlGroup } from './component/control_group_component'; -import { PresentationOverlaysService } from '../../../services/overlays'; -import { CONTROL_GROUP_TYPE, DEFAULT_CONTROL_WIDTH } from './control_group_constants'; -import { ManageControlGroup } from './editor/manage_control_group_component'; -import { OverlayRef } from '../../../../../../core/public'; -import { ControlGroupStrings } from './control_group_strings'; - -export class ControlGroupContainer extends Container<InputControlInput, ControlGroupInput> { - public readonly type = CONTROL_GROUP_TYPE; - - private nextControlWidth: ControlWidth = DEFAULT_CONTROL_WIDTH; - - constructor( - initialInput: ControlGroupInput, - private readonly controlsService: ControlsService, - private readonly overlays: PresentationOverlaysService, - parent?: Container - ) { - super(initialInput, { embeddableLoaded: {} }, controlsService.getControlFactory, parent); - this.overlays = overlays; - this.controlsService = controlsService; - } - - protected createNewPanelState<TEmbeddableInput extends InputControlInput = InputControlInput>( - factory: EmbeddableFactory<InputControlInput, InputControlOutput, InputControlEmbeddable>, - partial: Partial<TEmbeddableInput> = {} - ): ControlPanelState<TEmbeddableInput> { - const panelState = super.createNewPanelState(factory, partial); - return { - order: 1, - width: this.nextControlWidth, - ...panelState, - } as ControlPanelState<TEmbeddableInput>; - } - - protected getInheritedInput(id: string): InputControlInput { - const { filters, query, timeRange, inheritParentState } = this.getInput(); - return { - filters: inheritParentState.useFilters ? filters : undefined, - query: inheritParentState.useQuery ? query : undefined, - timeRange: inheritParentState.useTimerange ? timeRange : undefined, - id, - }; - } - - public createNewControl = async (type: string) => { - const factory = this.controlsService.getControlFactory(type); - if (!factory) throw new EmbeddableFactoryNotFoundError(type); - - const initialInputPromise = new Promise<Omit<InputControlInput, 'id'>>((resolve, reject) => { - let inputToReturn: Partial<InputControlInput> = {}; - - const onCancel = (ref: OverlayRef) => { - this.overlays - .openConfirm(ControlGroupStrings.management.discardNewControl.getSubtitle(), { - confirmButtonText: ControlGroupStrings.management.discardNewControl.getConfirm(), - cancelButtonText: ControlGroupStrings.management.discardNewControl.getCancel(), - title: ControlGroupStrings.management.discardNewControl.getTitle(), - buttonColor: 'danger', - }) - .then((confirmed) => { - if (confirmed) { - reject(); - ref.close(); - } - }); - }; - - const flyoutInstance = this.overlays.openFlyout( - toMountPoint( - <ManageControlComponent - width={this.nextControlWidth} - updateTitle={(newTitle) => (inputToReturn.title = newTitle)} - updateWidth={(newWidth) => (this.nextControlWidth = newWidth)} - controlEditorComponent={(factory as IEditableControlFactory).getControlEditor?.({ - onChange: (partialInput) => { - inputToReturn = { ...inputToReturn, ...partialInput }; - }, - })} - onSave={() => { - resolve(inputToReturn); - flyoutInstance.close(); - }} - onCancel={() => onCancel(flyoutInstance)} - /> - ), - { - onClose: (flyout) => onCancel(flyout), - } - ); - }); - initialInputPromise.then( - async (explicitInput) => { - await this.addNewEmbeddable(type, explicitInput); - }, - () => {} // swallow promise rejection because it can be part of normal flow - ); - }; - - public editControl = async (embeddableId: string) => { - const panel = this.getInput().panels[embeddableId]; - const factory = this.getFactory(panel.type); - const embeddable = await this.untilEmbeddableLoaded(embeddableId); - - if (!factory) throw new EmbeddableFactoryNotFoundError(panel.type); - - const initialExplicitInput = cloneDeep(panel.explicitInput); - const initialWidth = panel.width; - - const onCancel = (ref: OverlayRef) => { - this.overlays - .openConfirm(ControlGroupStrings.management.discardChanges.getSubtitle(), { - confirmButtonText: ControlGroupStrings.management.discardChanges.getConfirm(), - cancelButtonText: ControlGroupStrings.management.discardChanges.getCancel(), - title: ControlGroupStrings.management.discardChanges.getTitle(), - buttonColor: 'danger', - }) - .then((confirmed) => { - if (confirmed) { - embeddable.updateInput(initialExplicitInput); - this.updateInput({ - panels: { - ...this.getInput().panels, - [embeddableId]: { ...this.getInput().panels[embeddableId], width: initialWidth }, - }, - }); - ref.close(); - } - }); - }; - - const flyoutInstance = this.overlays.openFlyout( - toMountPoint( - <ManageControlComponent - width={panel.width} - title={embeddable.getTitle()} - removeControl={() => this.removeEmbeddable(embeddableId)} - updateTitle={(newTitle) => embeddable.updateInput({ title: newTitle })} - controlEditorComponent={(factory as IEditableControlFactory).getControlEditor?.({ - onChange: (partialInput) => embeddable.updateInput(partialInput), - initialInput: embeddable.getInput(), - })} - onCancel={() => onCancel(flyoutInstance)} - onSave={() => flyoutInstance.close()} - updateWidth={(newWidth) => - this.updateInput({ - panels: { - ...this.getInput().panels, - [embeddableId]: { ...this.getInput().panels[embeddableId], width: newWidth }, - }, - }) - } - /> - ), - { - onClose: (flyout) => onCancel(flyout), - } - ); - }; - - public editControlGroup = () => { - const flyoutInstance = this.overlays.openFlyout( - toMountPoint( - <ManageControlGroup - controlStyle={this.getInput().controlStyle} - setControlStyle={(newStyle) => this.updateInput({ controlStyle: newStyle })} - deleteAllEmbeddables={() => { - this.overlays - .openConfirm(ControlGroupStrings.management.deleteAllControls.getSubtitle(), { - confirmButtonText: ControlGroupStrings.management.deleteAllControls.getConfirm(), - cancelButtonText: ControlGroupStrings.management.deleteAllControls.getCancel(), - title: ControlGroupStrings.management.deleteAllControls.getTitle(), - buttonColor: 'danger', - }) - .then((confirmed) => { - if (confirmed) { - Object.keys(this.getInput().panels).forEach((id) => this.removeEmbeddable(id)); - flyoutInstance.close(); - } - }); - }} - setAllPanelWidths={(newWidth) => { - const newPanels = cloneDeep(this.getInput().panels); - Object.values(newPanels).forEach((panel) => (panel.width = newWidth)); - this.updateInput({ panels: { ...newPanels, ...newPanels } }); - }} - panels={this.getInput().panels} - /> - ) - ); - }; - - public render(dom: HTMLElement) { - ReactDOM.render(<ControlGroup controlGroupContainer={this} />, dom); - } -} diff --git a/src/plugins/presentation_util/public/components/controls/control_group/control_group_strings.ts b/src/plugins/presentation_util/public/components/controls/control_group/control_group_strings.ts index 78e50d8651931..35e490b0ea530 100644 --- a/src/plugins/presentation_util/public/components/controls/control_group/control_group_strings.ts +++ b/src/plugins/presentation_util/public/components/controls/control_group/control_group_strings.ts @@ -48,13 +48,9 @@ export const ControlGroupStrings = { i18n.translate('presentationUtil.inputControls.controlGroup.management.flyoutTitle', { defaultMessage: 'Manage controls', }), - getDesignTitle: () => - i18n.translate('presentationUtil.inputControls.controlGroup.management.designTitle', { - defaultMessage: 'Design', - }), - getWidthTitle: () => - i18n.translate('presentationUtil.inputControls.controlGroup.management.widthTitle', { - defaultMessage: 'Width', + getDefaultWidthTitle: () => + i18n.translate('presentationUtil.inputControls.controlGroup.management.defaultWidthTitle', { + defaultMessage: 'Default width', }), getLayoutTitle: () => i18n.translate('presentationUtil.inputControls.controlGroup.management.layoutTitle', { @@ -64,23 +60,20 @@ export const ControlGroupStrings = { i18n.translate('presentationUtil.inputControls.controlGroup.management.delete', { defaultMessage: 'Delete control', }), + getSetAllWidthsToDefaultTitle: () => + i18n.translate('presentationUtil.inputControls.controlGroup.management.setAllWidths', { + defaultMessage: 'Set all widths to default', + }), getDeleteAllButtonTitle: () => i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteAll', { defaultMessage: 'Delete all', }), controlWidth: { - getChangeAllControlWidthsTitle: () => - i18n.translate( - 'presentationUtil.inputControls.controlGroup.management.layout.changeAllControlWidths', - { - defaultMessage: 'Set width for all controls', - } - ), getWidthSwitchLegend: () => i18n.translate( 'presentationUtil.inputControls.controlGroup.management.layout.controlWidthLegend', { - defaultMessage: 'Change individual control width', + defaultMessage: 'Change control width', } ), getAutoWidthTitle: () => @@ -117,21 +110,31 @@ export const ControlGroupStrings = { defaultMessage: 'Two line layout', }), }, - deleteAllControls: { - getTitle: () => - i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteAll.title', { - defaultMessage: 'Delete all?', - }), + deleteControls: { + getDeleteAllTitle: () => + i18n.translate( + 'presentationUtil.inputControls.controlGroup.management.delete.deleteAllTitle', + { + defaultMessage: 'Delete all controls?', + } + ), + getDeleteTitle: () => + i18n.translate( + 'presentationUtil.inputControls.controlGroup.management.delete.deleteTitle', + { + defaultMessage: 'Delete control?', + } + ), getSubtitle: () => - i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteAll.sub', { + i18n.translate('presentationUtil.inputControls.controlGroup.management.delete.sub', { defaultMessage: 'Controls are not recoverable once removed.', }), getConfirm: () => - i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteAll.confirm', { + i18n.translate('presentationUtil.inputControls.controlGroup.management.delete.confirm', { defaultMessage: 'Delete', }), getCancel: () => - i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteAll.cancel', { + i18n.translate('presentationUtil.inputControls.controlGroup.management.delete.cancel', { defaultMessage: 'Cancel', }), }, @@ -143,7 +146,7 @@ export const ControlGroupStrings = { getSubtitle: () => i18n.translate('presentationUtil.inputControls.controlGroup.management.discard.sub', { defaultMessage: - 'Discard changes to this control? Controls are not recoverable once removed.', + 'Discard changes to this control? Changes are not recoverable once discardsd.', }), getConfirm: () => i18n.translate('presentationUtil.inputControls.controlGroup.management.discard.confirm', { @@ -161,7 +164,7 @@ export const ControlGroupStrings = { }), getSubtitle: () => i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteNew.sub', { - defaultMessage: 'Discard new control? Controls are not recoverable once removed.', + defaultMessage: 'Discard new control? Controls are not recoverable once discarded.', }), getConfirm: () => i18n.translate('presentationUtil.inputControls.controlGroup.management.deleteNew.confirm', { @@ -173,4 +176,14 @@ export const ControlGroupStrings = { }), }, }, + floatingActions: { + getEditButtonTitle: () => + i18n.translate('presentationUtil.inputControls.controlGroup.floatingActions.editTitle', { + defaultMessage: 'Manage control', + }), + getRemoveButtonTitle: () => + i18n.translate('presentationUtil.inputControls.controlGroup.floatingActions.removeTitle', { + defaultMessage: 'Remove control', + }), + }, }; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/editor/manage_control.tsx b/src/plugins/presentation_util/public/components/controls/control_group/editor/control_editor.tsx similarity index 99% rename from src/plugins/presentation_util/public/components/controls/control_group/editor/manage_control.tsx rename to src/plugins/presentation_util/public/components/controls/control_group/editor/control_editor.tsx index 6d80a6e0b31f6..38d8faf37397a 100644 --- a/src/plugins/presentation_util/public/components/controls/control_group/editor/manage_control.tsx +++ b/src/plugins/presentation_util/public/components/controls/control_group/editor/control_editor.tsx @@ -46,7 +46,7 @@ interface ManageControlProps { updateWidth: (newWidth: ControlWidth) => void; } -export const ManageControlComponent = ({ +export const ControlEditor = ({ controlEditorComponent, removeControl, updateTitle, diff --git a/src/plugins/presentation_util/public/components/controls/control_group/editor/create_control.tsx b/src/plugins/presentation_util/public/components/controls/control_group/editor/create_control.tsx new file mode 100644 index 0000000000000..9f59fe98cc0c1 --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/control_group/editor/create_control.tsx @@ -0,0 +1,158 @@ +/* + * Copyright 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 { + EuiButtonIcon, + EuiButtonIconColor, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiPopover, +} from '@elastic/eui'; +import React, { useState, ReactElement } from 'react'; + +import { ControlGroupInput } from '../types'; +import { ControlEditor } from './control_editor'; +import { pluginServices } from '../../../../services'; +import { forwardAllContext } from './forward_all_context'; +import { OverlayRef } from '../../../../../../../core/public'; +import { ControlGroupStrings } from '../control_group_strings'; +import { InputControlInput } from '../../../../services/controls'; +import { DEFAULT_CONTROL_WIDTH } from '../control_group_constants'; +import { ControlWidth, IEditableControlFactory } from '../../types'; +import { controlGroupReducers } from '../state/control_group_reducers'; +import { EmbeddableFactoryNotFoundError } from '../../../../../../embeddable/public'; +import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context'; + +export const CreateControlButton = () => { + // Presentation Services Context + const { overlays, controls } = pluginServices.getHooks(); + const { getInputControlTypes, getControlFactory } = controls.useService(); + const { openFlyout, openConfirm } = overlays.useService(); + + // Redux embeddable container Context + const reduxContainerContext = useReduxContainerContext< + ControlGroupInput, + typeof controlGroupReducers + >(); + const { + containerActions: { addNewEmbeddable }, + actions: { setDefaultControlWidth }, + useEmbeddableSelector, + useEmbeddableDispatch, + } = reduxContainerContext; + const dispatch = useEmbeddableDispatch(); + + // current state + const { defaultControlWidth } = useEmbeddableSelector((state) => state); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const createNewControl = async (type: string) => { + const factory = getControlFactory(type); + if (!factory) throw new EmbeddableFactoryNotFoundError(type); + + const initialInputPromise = new Promise<Omit<InputControlInput, 'id'>>((resolve, reject) => { + let inputToReturn: Partial<InputControlInput> = {}; + + const onCancel = (ref: OverlayRef) => { + if (Object.keys(inputToReturn).length === 0) { + reject(); + ref.close(); + return; + } + openConfirm(ControlGroupStrings.management.discardNewControl.getSubtitle(), { + confirmButtonText: ControlGroupStrings.management.discardNewControl.getConfirm(), + cancelButtonText: ControlGroupStrings.management.discardNewControl.getCancel(), + title: ControlGroupStrings.management.discardNewControl.getTitle(), + buttonColor: 'danger', + }).then((confirmed) => { + if (confirmed) { + reject(); + ref.close(); + } + }); + }; + + const flyoutInstance = openFlyout( + forwardAllContext( + <ControlEditor + width={defaultControlWidth ?? DEFAULT_CONTROL_WIDTH} + updateTitle={(newTitle) => (inputToReturn.title = newTitle)} + updateWidth={(newWidth) => dispatch(setDefaultControlWidth(newWidth as ControlWidth))} + controlEditorComponent={(factory as IEditableControlFactory).getControlEditor?.({ + onChange: (partialInput) => { + inputToReturn = { ...inputToReturn, ...partialInput }; + }, + })} + onSave={() => { + resolve(inputToReturn); + flyoutInstance.close(); + }} + onCancel={() => onCancel(flyoutInstance)} + />, + reduxContainerContext + ), + { + onClose: (flyout) => onCancel(flyout), + } + ); + }); + initialInputPromise.then( + async (explicitInput) => { + await addNewEmbeddable(type, explicitInput); + }, + () => {} // swallow promise rejection because it can be part of normal flow + ); + }; + + if (getInputControlTypes().length === 0) return null; + + const commonButtonProps = { + iconType: 'plus', + color: 'text' as EuiButtonIconColor, + 'data-test-subj': 'inputControlsSortingButton', + 'aria-label': ControlGroupStrings.management.getManageButtonTitle(), + }; + + if (getInputControlTypes().length > 1) { + const items: ReactElement[] = []; + getInputControlTypes().forEach((type) => { + const factory = getControlFactory(type); + items.push( + <EuiContextMenuItem + key={type} + icon={factory.getIconType?.()} + onClick={() => { + setIsPopoverOpen(false); + createNewControl(type); + }} + > + {factory.getDisplayName()} + </EuiContextMenuItem> + ); + }); + const button = <EuiButtonIcon {...commonButtonProps} onClick={() => setIsPopoverOpen(true)} />; + + return ( + <EuiPopover + button={button} + isOpen={isPopoverOpen} + panelPaddingSize="none" + anchorPosition="downLeft" + closePopover={() => setIsPopoverOpen(false)} + > + <EuiContextMenuPanel size="s" items={items} /> + </EuiPopover> + ); + } + return ( + <EuiButtonIcon + {...commonButtonProps} + onClick={() => createNewControl(getInputControlTypes()[0])} + /> + ); +}; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/editor/edit_control.tsx b/src/plugins/presentation_util/public/components/controls/control_group/editor/edit_control.tsx new file mode 100644 index 0000000000000..58c59c8f84fe0 --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/control_group/editor/edit_control.tsx @@ -0,0 +1,127 @@ +/* + * Copyright 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 { isEqual } from 'lodash'; +import { EuiButtonIcon } from '@elastic/eui'; +import React, { useEffect, useRef } from 'react'; + +import { ControlGroupInput } from '../types'; +import { ControlEditor } from './control_editor'; +import { IEditableControlFactory } from '../../types'; +import { pluginServices } from '../../../../services'; +import { forwardAllContext } from './forward_all_context'; +import { OverlayRef } from '../../../../../../../core/public'; +import { ControlGroupStrings } from '../control_group_strings'; +import { controlGroupReducers } from '../state/control_group_reducers'; +import { EmbeddableFactoryNotFoundError } from '../../../../../../embeddable/public'; +import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context'; + +export const EditControlButton = ({ embeddableId }: { embeddableId: string }) => { + // Presentation Services Context + const { overlays, controls } = pluginServices.getHooks(); + const { getControlFactory } = controls.useService(); + const { openFlyout, openConfirm } = overlays.useService(); + + // Redux embeddable container Context + const reduxContainerContext = useReduxContainerContext< + ControlGroupInput, + typeof controlGroupReducers + >(); + const { + containerActions: { untilEmbeddableLoaded, removeEmbeddable, updateInputForChild }, + actions: { setControlWidth }, + useEmbeddableSelector, + useEmbeddableDispatch, + } = reduxContainerContext; + const dispatch = useEmbeddableDispatch(); + + // current state + const { panels } = useEmbeddableSelector((state) => state); + + // keep up to date ref of latest panel state for comparison when closing editor. + const latestPanelState = useRef(panels[embeddableId]); + useEffect(() => { + latestPanelState.current = panels[embeddableId]; + }, [panels, embeddableId]); + + const editControl = async () => { + const panel = panels[embeddableId]; + const factory = getControlFactory(panel.type); + const embeddable = await untilEmbeddableLoaded(embeddableId); + + if (!factory) throw new EmbeddableFactoryNotFoundError(panel.type); + + let removed = false; + const onCancel = (ref: OverlayRef) => { + if ( + removed || + (isEqual(latestPanelState.current.explicitInput, panel.explicitInput) && + isEqual(latestPanelState.current.width, panel.width)) + ) { + ref.close(); + return; + } + openConfirm(ControlGroupStrings.management.discardChanges.getSubtitle(), { + confirmButtonText: ControlGroupStrings.management.discardChanges.getConfirm(), + cancelButtonText: ControlGroupStrings.management.discardChanges.getCancel(), + title: ControlGroupStrings.management.discardChanges.getTitle(), + buttonColor: 'danger', + }).then((confirmed) => { + if (confirmed) { + updateInputForChild(embeddableId, panel.explicitInput); + dispatch(setControlWidth({ width: panel.width, embeddableId })); + ref.close(); + } + }); + }; + + const flyoutInstance = openFlyout( + forwardAllContext( + <ControlEditor + width={panel.width} + title={embeddable.getTitle()} + removeControl={() => { + openConfirm(ControlGroupStrings.management.deleteControls.getSubtitle(), { + confirmButtonText: ControlGroupStrings.management.deleteControls.getConfirm(), + cancelButtonText: ControlGroupStrings.management.deleteControls.getCancel(), + title: ControlGroupStrings.management.deleteControls.getDeleteTitle(), + buttonColor: 'danger', + }).then((confirmed) => { + if (confirmed) { + removeEmbeddable(embeddableId); + removed = true; + flyoutInstance.close(); + } + }); + }} + updateTitle={(newTitle) => updateInputForChild(embeddableId, { title: newTitle })} + controlEditorComponent={(factory as IEditableControlFactory).getControlEditor?.({ + onChange: (partialInput) => updateInputForChild(embeddableId, partialInput), + initialInput: embeddable.getInput(), + })} + onCancel={() => onCancel(flyoutInstance)} + onSave={() => flyoutInstance.close()} + updateWidth={(newWidth) => dispatch(setControlWidth({ width: newWidth, embeddableId }))} + />, + reduxContainerContext + ), + { + onClose: (flyout) => onCancel(flyout), + } + ); + }; + + return ( + <EuiButtonIcon + aria-label={ControlGroupStrings.floatingActions.getEditButtonTitle()} + iconType="pencil" + onClick={() => editControl()} + color="text" + /> + ); +}; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/editor/edit_control_group.tsx b/src/plugins/presentation_util/public/components/controls/control_group/editor/edit_control_group.tsx new file mode 100644 index 0000000000000..9438091e2fb1d --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/control_group/editor/edit_control_group.tsx @@ -0,0 +1,124 @@ +/* + * Copyright 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 { + EuiTitle, + EuiSpacer, + EuiFormRow, + EuiFlexItem, + EuiFlexGroup, + EuiFlyoutBody, + EuiButtonGroup, + EuiButtonEmpty, + EuiFlyoutHeader, +} from '@elastic/eui'; + +import { + CONTROL_LAYOUT_OPTIONS, + CONTROL_WIDTH_OPTIONS, + DEFAULT_CONTROL_WIDTH, +} from '../control_group_constants'; +import { ControlGroupInput } from '../types'; +import { pluginServices } from '../../../../services'; +import { ControlStyle, ControlWidth } from '../../types'; +import { ControlGroupStrings } from '../control_group_strings'; +import { controlGroupReducers } from '../state/control_group_reducers'; +import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context'; + +export const EditControlGroup = () => { + const { overlays } = pluginServices.getHooks(); + const { openConfirm } = overlays.useService(); + + const { + containerActions, + useEmbeddableSelector, + useEmbeddableDispatch, + actions: { setControlStyle, setAllControlWidths, setDefaultControlWidth }, + } = useReduxContainerContext<ControlGroupInput, typeof controlGroupReducers>(); + + const dispatch = useEmbeddableDispatch(); + const { panels, controlStyle, defaultControlWidth } = useEmbeddableSelector((state) => state); + + return ( + <> + <EuiFlyoutHeader hasBorder> + <EuiTitle size="m"> + <h2>{ControlGroupStrings.management.getFlyoutTitle()}</h2> + </EuiTitle> + </EuiFlyoutHeader> + <EuiFlyoutBody> + <EuiFormRow label={ControlGroupStrings.management.getLayoutTitle()}> + <EuiButtonGroup + color="primary" + legend={ControlGroupStrings.management.controlStyle.getDesignSwitchLegend()} + options={CONTROL_LAYOUT_OPTIONS} + idSelected={controlStyle} + onChange={(newControlStyle) => + dispatch(setControlStyle(newControlStyle as ControlStyle)) + } + /> + </EuiFormRow> + <EuiSpacer size="m" /> + <EuiFormRow label={ControlGroupStrings.management.getDefaultWidthTitle()}> + <EuiFlexGroup direction={'row'}> + <EuiFlexItem> + <EuiButtonGroup + color="primary" + idSelected={defaultControlWidth ?? DEFAULT_CONTROL_WIDTH} + legend={ControlGroupStrings.management.controlWidth.getWidthSwitchLegend()} + options={CONTROL_WIDTH_OPTIONS} + onChange={(newWidth: string) => + dispatch(setDefaultControlWidth(newWidth as ControlWidth)) + } + /> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={() => + dispatch(setAllControlWidths(defaultControlWidth ?? DEFAULT_CONTROL_WIDTH)) + } + aria-label={'delete-all'} + iconType="returnKey" + size="s" + > + {ControlGroupStrings.management.getSetAllWidthsToDefaultTitle()} + </EuiButtonEmpty> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFormRow> + + <EuiSpacer size="xl" /> + + <EuiButtonEmpty + onClick={() => { + if (!containerActions?.removeEmbeddable) return; + openConfirm(ControlGroupStrings.management.deleteControls.getSubtitle(), { + confirmButtonText: ControlGroupStrings.management.deleteControls.getConfirm(), + cancelButtonText: ControlGroupStrings.management.deleteControls.getCancel(), + title: ControlGroupStrings.management.deleteControls.getDeleteAllTitle(), + buttonColor: 'danger', + }).then((confirmed) => { + if (confirmed) + Object.keys(panels).forEach((panelId) => + containerActions.removeEmbeddable(panelId) + ); + }); + }} + aria-label={'delete-all'} + iconType="trash" + color="danger" + flush="left" + size="s" + > + {ControlGroupStrings.management.getDeleteAllButtonTitle()} + </EuiButtonEmpty> + </EuiFlyoutBody> + </> + ); +}; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/editor/forward_all_context.tsx b/src/plugins/presentation_util/public/components/controls/control_group/editor/forward_all_context.tsx new file mode 100644 index 0000000000000..bb7356c240648 --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/control_group/editor/forward_all_context.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { Provider } from 'react-redux'; +import { ReactElement } from 'react'; +import React from 'react'; + +import { ControlGroupInput } from '../types'; +import { pluginServices } from '../../../../services'; +import { toMountPoint } from '../../../../../../kibana_react/public'; +import { ReduxContainerContextServices } from '../../../redux_embeddables/types'; +import { ReduxEmbeddableContext } from '../../../redux_embeddables/redux_embeddable_context'; +import { getManagedEmbeddablesStore } from '../../../redux_embeddables/generic_embeddable_store'; + +/** + * The overlays service creates its divs outside the flow of the component. This necessitates + * passing all context from the component to the flyout. + */ +export const forwardAllContext = ( + component: ReactElement, + reduxContainerContext: ReduxContainerContextServices<ControlGroupInput> +) => { + const PresentationUtilProvider = pluginServices.getContextProvider(); + return toMountPoint( + <Provider store={getManagedEmbeddablesStore()}> + <ReduxEmbeddableContext.Provider value={reduxContainerContext}> + <PresentationUtilProvider>{component}</PresentationUtilProvider> + </ReduxEmbeddableContext.Provider> + </Provider> + ); +}; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/editor/manage_control_group_component.tsx b/src/plugins/presentation_util/public/components/controls/control_group/editor/manage_control_group_component.tsx deleted file mode 100644 index e766b16ade13a..0000000000000 --- a/src/plugins/presentation_util/public/components/controls/control_group/editor/manage_control_group_component.tsx +++ /dev/null @@ -1,113 +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 useMount from 'react-use/lib/useMount'; -import React, { useState } from 'react'; -import { - EuiFlyoutHeader, - EuiButtonEmpty, - EuiButtonGroup, - EuiFlyoutBody, - EuiFormRow, - EuiSpacer, - EuiSwitch, - EuiTitle, -} from '@elastic/eui'; - -import { ControlsPanels } from '../types'; -import { ControlStyle, ControlWidth } from '../../types'; -import { ControlGroupStrings } from '../control_group_strings'; -import { CONTROL_LAYOUT_OPTIONS, CONTROL_WIDTH_OPTIONS } from '../control_group_constants'; - -interface ManageControlGroupProps { - panels: ControlsPanels; - controlStyle: ControlStyle; - deleteAllEmbeddables: () => void; - setControlStyle: (style: ControlStyle) => void; - setAllPanelWidths: (newWidth: ControlWidth) => void; -} - -export const ManageControlGroup = ({ - panels, - controlStyle, - setControlStyle, - setAllPanelWidths, - deleteAllEmbeddables, -}: ManageControlGroupProps) => { - const [currentControlStyle, setCurrentControlStyle] = useState<ControlStyle>(controlStyle); - const [selectedWidth, setSelectedWidth] = useState<ControlWidth>(); - const [selectionDisplay, setSelectionDisplay] = useState(false); - - useMount(() => { - if (!panels || Object.keys(panels).length === 0) return; - const firstWidth = panels[Object.keys(panels)[0]].width; - if (Object.values(panels).every((panel) => panel.width === firstWidth)) { - setSelectedWidth(firstWidth); - } - }); - - return ( - <> - <EuiFlyoutHeader hasBorder> - <EuiTitle size="m"> - <h2>{ControlGroupStrings.management.getFlyoutTitle()}</h2> - </EuiTitle> - </EuiFlyoutHeader> - <EuiFlyoutBody> - <EuiFormRow label={ControlGroupStrings.management.getLayoutTitle()}> - <EuiButtonGroup - color="primary" - legend={ControlGroupStrings.management.controlStyle.getDesignSwitchLegend()} - options={CONTROL_LAYOUT_OPTIONS} - idSelected={currentControlStyle} - onChange={(newControlStyle) => { - setControlStyle(newControlStyle as ControlStyle); - setCurrentControlStyle(newControlStyle as ControlStyle); - }} - /> - </EuiFormRow> - <EuiSpacer size="m" /> - <EuiFormRow label={ControlGroupStrings.management.getWidthTitle()}> - <EuiSwitch - label={ControlGroupStrings.management.controlWidth.getChangeAllControlWidthsTitle()} - checked={selectionDisplay} - onChange={() => setSelectionDisplay(!selectionDisplay)} - /> - </EuiFormRow> - {selectionDisplay ? ( - <> - <EuiSpacer size="s" /> - <EuiButtonGroup - color="primary" - idSelected={selectedWidth ?? ''} - legend={ControlGroupStrings.management.controlWidth.getWidthSwitchLegend()} - options={CONTROL_WIDTH_OPTIONS} - onChange={(newWidth: string) => { - setAllPanelWidths(newWidth as ControlWidth); - setSelectedWidth(newWidth as ControlWidth); - }} - /> - </> - ) : undefined} - - <EuiSpacer size="xl" /> - - <EuiButtonEmpty - onClick={deleteAllEmbeddables} - aria-label={'delete-all'} - iconType="trash" - color="danger" - flush="left" - size="s" - > - {ControlGroupStrings.management.getDeleteAllButtonTitle()} - </EuiButtonEmpty> - </EuiFlyoutBody> - </> - ); -}; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/embeddable/control_group_container.tsx b/src/plugins/presentation_util/public/components/controls/control_group/embeddable/control_group_container.tsx new file mode 100644 index 0000000000000..a722bed6c07d2 --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/control_group/embeddable/control_group_container.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; + +import { + InputControlEmbeddable, + InputControlInput, + InputControlOutput, +} from '../../../../services/controls'; +import { pluginServices } from '../../../../services'; +import { ControlGroupInput, ControlPanelState } from '../types'; +import { ControlGroup } from '../component/control_group_component'; +import { controlGroupReducers } from '../state/control_group_reducers'; +import { Container, EmbeddableFactory } from '../../../../../../embeddable/public'; +import { CONTROL_GROUP_TYPE, DEFAULT_CONTROL_WIDTH } from '../control_group_constants'; +import { ReduxEmbeddableWrapper } from '../../../redux_embeddables/redux_embeddable_wrapper'; + +export class ControlGroupContainer extends Container<InputControlInput, ControlGroupInput> { + public readonly type = CONTROL_GROUP_TYPE; + + constructor(initialInput: ControlGroupInput, parent?: Container) { + super( + initialInput, + { embeddableLoaded: {} }, + pluginServices.getServices().controls.getControlFactory, + parent + ); + } + + protected createNewPanelState<TEmbeddableInput extends InputControlInput = InputControlInput>( + factory: EmbeddableFactory<InputControlInput, InputControlOutput, InputControlEmbeddable>, + partial: Partial<TEmbeddableInput> = {} + ): ControlPanelState<TEmbeddableInput> { + const panelState = super.createNewPanelState(factory, partial); + const highestOrder = Object.values(this.getInput().panels).reduce((highestSoFar, panel) => { + if (panel.order > highestSoFar) highestSoFar = panel.order; + return highestSoFar; + }, 0); + return { + order: highestOrder + 1, + width: this.getInput().defaultControlWidth ?? DEFAULT_CONTROL_WIDTH, + ...panelState, + } as ControlPanelState<TEmbeddableInput>; + } + + protected getInheritedInput(id: string): InputControlInput { + const { filters, query, timeRange, inheritParentState } = this.getInput(); + return { + filters: inheritParentState.useFilters ? filters : undefined, + query: inheritParentState.useQuery ? query : undefined, + timeRange: inheritParentState.useTimerange ? timeRange : undefined, + id, + }; + } + + public render(dom: HTMLElement) { + const PresentationUtilProvider = pluginServices.getContextProvider(); + ReactDOM.render( + <PresentationUtilProvider> + <ReduxEmbeddableWrapper<ControlGroupInput> + embeddable={this} + reducers={controlGroupReducers} + > + <ControlGroup /> + </ReduxEmbeddableWrapper> + </PresentationUtilProvider>, + dom + ); + } +} diff --git a/src/plugins/presentation_util/public/components/controls/control_group/control_group_container_factory.ts b/src/plugins/presentation_util/public/components/controls/control_group/embeddable/control_group_container_factory.ts similarity index 71% rename from src/plugins/presentation_util/public/components/controls/control_group/control_group_container_factory.ts rename to src/plugins/presentation_util/public/components/controls/control_group/embeddable/control_group_container_factory.ts index 97ef48e6b240c..e50b1c5d734e4 100644 --- a/src/plugins/presentation_util/public/components/controls/control_group/control_group_container_factory.ts +++ b/src/plugins/presentation_util/public/components/controls/control_group/embeddable/control_group_container_factory.ts @@ -20,13 +20,11 @@ import { EmbeddableFactory, EmbeddableFactoryDefinition, ErrorEmbeddable, -} from '../../../../../embeddable/public'; -import { ControlGroupInput } from './types'; -import { ControlsService } from '../controls_service'; -import { ControlGroupStrings } from './control_group_strings'; -import { CONTROL_GROUP_TYPE } from './control_group_constants'; +} from '../../../../../../embeddable/public'; +import { ControlGroupInput } from '../types'; +import { ControlGroupStrings } from '../control_group_strings'; +import { CONTROL_GROUP_TYPE } from '../control_group_constants'; import { ControlGroupContainer } from './control_group_container'; -import { PresentationOverlaysService } from '../../../services/overlays'; export type DashboardContainerFactory = EmbeddableFactory< ControlGroupInput, @@ -38,13 +36,6 @@ export class ControlGroupContainerFactory { public readonly isContainerType = true; public readonly type = CONTROL_GROUP_TYPE; - public readonly controlsService: ControlsService; - private readonly overlays: PresentationOverlaysService; - - constructor(controlsService: ControlsService, overlays: PresentationOverlaysService) { - this.overlays = overlays; - this.controlsService = controlsService; - } public isEditable = async () => false; @@ -67,6 +58,6 @@ export class ControlGroupContainerFactory initialInput: ControlGroupInput, parent?: Container ): Promise<ControlGroupContainer | ErrorEmbeddable> => { - return new ControlGroupContainer(initialInput, this.controlsService, this.overlays, parent); + return new ControlGroupContainer(initialInput, parent); }; } diff --git a/src/plugins/presentation_util/public/components/controls/control_group/state/control_group_reducers.ts b/src/plugins/presentation_util/public/components/controls/control_group/state/control_group_reducers.ts new file mode 100644 index 0000000000000..b7c0c62535d4c --- /dev/null +++ b/src/plugins/presentation_util/public/components/controls/control_group/state/control_group_reducers.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PayloadAction } from '@reduxjs/toolkit'; +import { WritableDraft } from 'immer/dist/types/types-external'; + +import { ControlWidth } from '../../types'; +import { ControlGroupInput } from '../types'; + +export const controlGroupReducers = { + setControlStyle: ( + state: WritableDraft<ControlGroupInput>, + action: PayloadAction<ControlGroupInput['controlStyle']> + ) => { + state.controlStyle = action.payload; + }, + setDefaultControlWidth: ( + state: WritableDraft<ControlGroupInput>, + action: PayloadAction<ControlGroupInput['defaultControlWidth']> + ) => { + state.defaultControlWidth = action.payload; + }, + setAllControlWidths: ( + state: WritableDraft<ControlGroupInput>, + action: PayloadAction<ControlWidth> + ) => { + Object.keys(state.panels).forEach((panelId) => (state.panels[panelId].width = action.payload)); + }, + setControlWidth: ( + state: WritableDraft<ControlGroupInput>, + action: PayloadAction<{ width: ControlWidth; embeddableId: string }> + ) => { + state.panels[action.payload.embeddableId].width = action.payload.width; + }, + setControlOrders: ( + state: WritableDraft<ControlGroupInput>, + action: PayloadAction<{ ids: string[] }> + ) => { + action.payload.ids.forEach((id, index) => { + state.panels[id].order = index; + }); + }, +}; diff --git a/src/plugins/presentation_util/public/components/controls/control_group/types.ts b/src/plugins/presentation_util/public/components/controls/control_group/types.ts index fb381610711e5..438eee1c461dd 100644 --- a/src/plugins/presentation_util/public/components/controls/control_group/types.ts +++ b/src/plugins/presentation_util/public/components/controls/control_group/types.ts @@ -7,7 +7,8 @@ */ import { PanelState, EmbeddableInput } from '../../../../../embeddable/public'; -import { ControlStyle, ControlWidth, InputControlInput } from '../types'; +import { InputControlInput } from '../../../services/controls'; +import { ControlStyle, ControlWidth } from '../types'; export interface ControlGroupInput extends EmbeddableInput, @@ -17,6 +18,7 @@ export interface ControlGroupInput useQuery: boolean; useTimerange: boolean; }; + defaultControlWidth?: ControlWidth; controlStyle: ControlStyle; panels: ControlsPanels; } diff --git a/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx b/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx index 93a7b3e353bdf..97a128c3e84eb 100644 --- a/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx +++ b/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx @@ -16,7 +16,7 @@ import { tap, debounceTime, map, distinctUntilChanged } from 'rxjs/operators'; import { esFilters } from '../../../../../../data/public'; import { OptionsListStrings } from './options_list_strings'; import { Embeddable, IContainer } from '../../../../../../embeddable/public'; -import { InputControlInput, InputControlOutput } from '../../types'; +import { InputControlInput, InputControlOutput } from '../../../../services/controls'; import { OptionsListComponent, OptionsListComponentState } from './options_list_component'; const toggleAvailableOptions = ( diff --git a/src/plugins/presentation_util/public/components/controls/controls_service.ts b/src/plugins/presentation_util/public/components/controls/controls_service.ts index 4e01f3cf9ab6a..82242946e4563 100644 --- a/src/plugins/presentation_util/public/components/controls/controls_service.ts +++ b/src/plugins/presentation_util/public/components/controls/controls_service.ts @@ -8,12 +8,12 @@ import { EmbeddableFactory } from '../../../../embeddable/public'; import { - ControlTypeRegistry, InputControlEmbeddable, + ControlTypeRegistry, InputControlFactory, - InputControlInput, InputControlOutput, -} from './types'; + InputControlInput, +} from '../../services/controls'; export class ControlsService { private controlsFactoriesMap: ControlTypeRegistry = {}; diff --git a/src/plugins/presentation_util/public/components/controls/hooks/use_child_embeddable.ts b/src/plugins/presentation_util/public/components/controls/hooks/use_child_embeddable.ts index 82b9aa528bf35..c4f700ec059d9 100644 --- a/src/plugins/presentation_util/public/components/controls/hooks/use_child_embeddable.ts +++ b/src/plugins/presentation_util/public/components/controls/hooks/use_child_embeddable.ts @@ -6,14 +6,13 @@ * Side Public License, v 1. */ import { useEffect, useState } from 'react'; -import { InputControlEmbeddable } from '../types'; -import { IContainer } from '../../../../../embeddable/public'; +import { InputControlEmbeddable } from '../../../services/controls'; export const useChildEmbeddable = ({ - container, + untilEmbeddableLoaded, embeddableId, }: { - container: IContainer; + untilEmbeddableLoaded: (embeddableId: string) => Promise<InputControlEmbeddable>; embeddableId: string; }) => { const [embeddable, setEmbeddable] = useState<InputControlEmbeddable>(); @@ -21,14 +20,14 @@ export const useChildEmbeddable = ({ useEffect(() => { let mounted = true; (async () => { - const newEmbeddable = await container.untilEmbeddableLoaded(embeddableId); + const newEmbeddable = await untilEmbeddableLoaded(embeddableId); if (!mounted) return; setEmbeddable(newEmbeddable); })(); return () => { mounted = false; }; - }, [container, embeddableId]); + }, [untilEmbeddableLoaded, embeddableId]); return embeddable; }; diff --git a/src/plugins/presentation_util/public/components/controls/types.ts b/src/plugins/presentation_util/public/components/controls/types.ts index c94e2957e34ea..0704a601640e6 100644 --- a/src/plugins/presentation_util/public/components/controls/types.ts +++ b/src/plugins/presentation_util/public/components/controls/types.ts @@ -6,47 +6,11 @@ * Side Public License, v 1. */ -import { Filter } from '@kbn/es-query'; -import { Query, TimeRange } from '../../../../data/public'; -import { - EmbeddableFactory, - EmbeddableInput, - EmbeddableOutput, - IEmbeddable, -} from '../../../../embeddable/public'; +import { InputControlInput } from '../../services/controls'; export type ControlWidth = 'auto' | 'small' | 'medium' | 'large'; export type ControlStyle = 'twoLine' | 'oneLine'; -/** - * Control embeddable types - */ -export type InputControlFactory = EmbeddableFactory< - InputControlInput, - InputControlOutput, - InputControlEmbeddable ->; - -export interface ControlTypeRegistry { - [key: string]: InputControlFactory; -} - -export type InputControlInput = EmbeddableInput & { - query?: Query; - filters?: Filter[]; - timeRange?: TimeRange; - twoLineLayout?: boolean; -}; - -export type InputControlOutput = EmbeddableOutput & { - filters?: Filter[]; -}; - -export type InputControlEmbeddable< - TInputControlEmbeddableInput extends InputControlInput = InputControlInput, - TInputControlEmbeddableOutput extends InputControlOutput = InputControlOutput -> = IEmbeddable<TInputControlEmbeddableInput, TInputControlEmbeddableOutput>; - /** * Control embeddable editor types */ diff --git a/src/plugins/presentation_util/public/components/redux_embeddables/generic_embeddable_store.ts b/src/plugins/presentation_util/public/components/redux_embeddables/generic_embeddable_store.ts new file mode 100644 index 0000000000000..36ba1fcaa49b9 --- /dev/null +++ b/src/plugins/presentation_util/public/components/redux_embeddables/generic_embeddable_store.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { configureStore, EnhancedStore } from '@reduxjs/toolkit'; +import { combineReducers, Reducer } from 'redux'; + +export interface InjectReducerProps<StateShape> { + key: string; + asyncReducer: Reducer<StateShape>; +} + +type ManagedEmbeddableReduxStore = EnhancedStore & { + asyncReducers: { [key: string]: Reducer<unknown> }; + injectReducer: <StateShape>(props: InjectReducerProps<StateShape>) => void; +}; +const embeddablesStore = configureStore({ reducer: {} as { [key: string]: Reducer } }); + +const managedEmbeddablesStore = embeddablesStore as ManagedEmbeddableReduxStore; +managedEmbeddablesStore.asyncReducers = {}; + +managedEmbeddablesStore.injectReducer = <StateShape>({ + key, + asyncReducer, +}: InjectReducerProps<StateShape>) => { + managedEmbeddablesStore.asyncReducers[key] = asyncReducer as Reducer<unknown>; + managedEmbeddablesStore.replaceReducer( + combineReducers({ ...managedEmbeddablesStore.asyncReducers }) + ); +}; + +/** + * A managed Redux store which can be used with multiple embeddables at once. When a new embeddable is created at runtime, + * all passed in reducers will be made into a slice, then combined into the store using combineReducers. + */ +export const getManagedEmbeddablesStore = () => managedEmbeddablesStore; diff --git a/src/plugins/presentation_util/public/components/redux_embeddables/redux_embeddable_context.ts b/src/plugins/presentation_util/public/components/redux_embeddables/redux_embeddable_context.ts new file mode 100644 index 0000000000000..159230e4de024 --- /dev/null +++ b/src/plugins/presentation_util/public/components/redux_embeddables/redux_embeddable_context.ts @@ -0,0 +1,73 @@ +/* + * Copyright 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 { createContext, useContext } from 'react'; + +import { + GenericEmbeddableReducers, + ReduxContainerContextServices, + ReduxEmbeddableContextServices, +} from './types'; +import { ContainerInput, EmbeddableInput } from '../../../../embeddable/public'; + +/** + * When creating the context, a generic EmbeddableInput as placeholder is used. This will later be cast to + * the generic type passed in by the useReduxEmbeddableContext or useReduxContainerContext hooks + **/ +export const ReduxEmbeddableContext = createContext< + | ReduxEmbeddableContextServices<EmbeddableInput> + | ReduxContainerContextServices<EmbeddableInput> + | null +>(null); + +/** + * A typed use context hook for embeddables that are not containers. it @returns an + * ReduxEmbeddableContextServices object typed to the generic inputTypes and ReducerTypes you pass in. + * Note that the reducer type is optional, but will be required to correctly infer the keys and payload + * types of your reducers. use `typeof MyReducers` here to retain them. + */ +export const useReduxEmbeddableContext = < + InputType extends EmbeddableInput = EmbeddableInput, + ReducerType extends GenericEmbeddableReducers<InputType> = GenericEmbeddableReducers<InputType> +>(): ReduxEmbeddableContextServices<InputType, ReducerType> => { + const context = useContext<ReduxEmbeddableContextServices<InputType, ReducerType>>( + ReduxEmbeddableContext as unknown as React.Context< + ReduxEmbeddableContextServices<InputType, ReducerType> + > + ); + if (context == null) { + throw new Error( + 'useReduxEmbeddableContext must be used inside the useReduxEmbeddableContextProvider.' + ); + } + + return context!; +}; + +/** + * A typed use context hook for embeddable containers. it @returns an + * ReduxContainerContextServices object typed to the generic inputTypes and ReducerTypes you pass in. + * Note that the reducer type is optional, but will be required to correctly infer the keys and payload + * types of your reducers. use `typeof MyReducers` here to retain them. It also includes a containerActions + * key which contains most of the commonly used container operations + */ +export const useReduxContainerContext = < + InputType extends ContainerInput = ContainerInput, + ReducerType extends GenericEmbeddableReducers<InputType> = GenericEmbeddableReducers<InputType> +>(): ReduxContainerContextServices<InputType, ReducerType> => { + const context = useContext<ReduxContainerContextServices<InputType, ReducerType>>( + ReduxEmbeddableContext as unknown as React.Context< + ReduxContainerContextServices<InputType, ReducerType> + > + ); + if (context == null) { + throw new Error( + 'useReduxEmbeddableContext must be used inside the useReduxEmbeddableContextProvider.' + ); + } + return context!; +}; diff --git a/src/plugins/presentation_util/public/components/redux_embeddables/redux_embeddable_wrapper.tsx b/src/plugins/presentation_util/public/components/redux_embeddables/redux_embeddable_wrapper.tsx new file mode 100644 index 0000000000000..a4912b5b5f2fc --- /dev/null +++ b/src/plugins/presentation_util/public/components/redux_embeddables/redux_embeddable_wrapper.tsx @@ -0,0 +1,162 @@ +/* + * Copyright 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, { PropsWithChildren, useEffect, useMemo, useRef } from 'react'; +import { Provider, TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; +import { Draft } from 'immer/dist/types/types-external'; +import { isEqual } from 'lodash'; +import { SliceCaseReducers, PayloadAction, createSlice } from '@reduxjs/toolkit'; + +import { + IEmbeddable, + EmbeddableInput, + EmbeddableOutput, + IContainer, +} from '../../../../embeddable/public'; +import { getManagedEmbeddablesStore } from './generic_embeddable_store'; +import { + ReduxContainerContextServices, + ReduxEmbeddableContextServices, + ReduxEmbeddableWrapperProps, +} from './types'; +import { ReduxEmbeddableContext, useReduxEmbeddableContext } from './redux_embeddable_context'; + +const getDefaultProps = <InputType extends EmbeddableInput = EmbeddableInput>(): Required< + Pick<ReduxEmbeddableWrapperProps<InputType>, 'diffInput'> +> => ({ + diffInput: (a, b) => { + const differences: Partial<InputType> = {}; + const allKeys = [...Object.keys(a), ...Object.keys(b)] as Array<keyof InputType>; + allKeys.forEach((key) => { + if (!isEqual(a[key], b[key])) differences[key] = a[key]; + }); + return differences; + }, +}); + +const embeddableIsContainer = ( + embeddable: IEmbeddable<EmbeddableInput, EmbeddableOutput> +): embeddable is IContainer => embeddable.isContainer; + +/** + * Place this wrapper around the react component when rendering an embeddable to automatically set up + * redux for use with the embeddable via the supplied reducers. Any child components can then use ReduxEmbeddableContext + * or ReduxContainerContext to interface with the state of the embeddable. + */ +export const ReduxEmbeddableWrapper = <InputType extends EmbeddableInput = EmbeddableInput>( + props: PropsWithChildren<ReduxEmbeddableWrapperProps<InputType>> +) => { + const { embeddable, reducers, diffInput } = useMemo( + () => ({ ...getDefaultProps<InputType>(), ...props }), + [props] + ); + + const containerActions: ReduxContainerContextServices['containerActions'] | undefined = + useMemo(() => { + if (embeddableIsContainer(embeddable)) { + return { + untilEmbeddableLoaded: embeddable.untilEmbeddableLoaded.bind(embeddable), + updateInputForChild: embeddable.updateInputForChild.bind(embeddable), + removeEmbeddable: embeddable.removeEmbeddable.bind(embeddable), + addNewEmbeddable: embeddable.addNewEmbeddable.bind(embeddable), + }; + } + return; + }, [embeddable]); + + const reduxEmbeddableContext: ReduxEmbeddableContextServices | ReduxContainerContextServices = + useMemo(() => { + const key = `${embeddable.type}_${embeddable.id}`; + + // A generic reducer used to update redux state when the embeddable input changes + const updateEmbeddableReduxState = ( + state: Draft<InputType>, + action: PayloadAction<Partial<InputType>> + ) => { + return { ...state, ...action.payload }; + }; + + const slice = createSlice<InputType, SliceCaseReducers<InputType>>({ + initialState: embeddable.getInput(), + name: key, + reducers: { ...reducers, updateEmbeddableReduxState }, + }); + const store = getManagedEmbeddablesStore(); + + store.injectReducer({ + key, + asyncReducer: slice.reducer, + }); + + const useEmbeddableSelector: TypedUseSelectorHook<InputType> = () => + useSelector((state: ReturnType<typeof store.getState>) => state[key]); + + return { + useEmbeddableDispatch: () => useDispatch<typeof store.dispatch>(), + useEmbeddableSelector, + actions: slice.actions as ReduxEmbeddableContextServices['actions'], + containerActions, + }; + }, [reducers, embeddable, containerActions]); + + return ( + <Provider store={getManagedEmbeddablesStore()}> + <ReduxEmbeddableContext.Provider value={reduxEmbeddableContext}> + <ReduxEmbeddableSync diffInput={diffInput} embeddable={embeddable}> + {props.children} + </ReduxEmbeddableSync> + </ReduxEmbeddableContext.Provider> + </Provider> + ); +}; + +interface ReduxEmbeddableSyncProps<InputType extends EmbeddableInput = EmbeddableInput> { + diffInput: (a: InputType, b: InputType) => Partial<InputType>; + embeddable: IEmbeddable<InputType, EmbeddableOutput>; +} + +/** + * This component uses the context from the embeddable wrapper to set up a generic two-way binding between the embeddable input and + * the redux store. a custom diffInput function can be provided, this function should always prioritize input A over input B. + */ +const ReduxEmbeddableSync = <InputType extends EmbeddableInput = EmbeddableInput>({ + embeddable, + diffInput, + children, +}: PropsWithChildren<ReduxEmbeddableSyncProps<InputType>>) => { + const { + useEmbeddableSelector, + useEmbeddableDispatch, + actions: { updateEmbeddableReduxState }, + } = useReduxEmbeddableContext<InputType>(); + + const dispatch = useEmbeddableDispatch(); + const currentState = useEmbeddableSelector((state) => state); + const stateRef = useRef(currentState); + + // When Embeddable Input changes, push differences to redux. + useEffect(() => { + embeddable.getInput$().subscribe(() => { + const differences = diffInput(embeddable.getInput(), stateRef.current); + if (differences && Object.keys(differences).length > 0) { + dispatch(updateEmbeddableReduxState(differences)); + } + }); + }, [diffInput, dispatch, embeddable, updateEmbeddableReduxState]); + + // When redux state changes, push differences to Embeddable Input. + useEffect(() => { + stateRef.current = currentState; + const differences = diffInput(currentState, embeddable.getInput()); + if (differences && Object.keys(differences).length > 0) { + embeddable.updateInput(differences); + } + }, [currentState, diffInput, embeddable]); + + return <>{children}</>; +}; diff --git a/src/plugins/presentation_util/public/components/redux_embeddables/types.ts b/src/plugins/presentation_util/public/components/redux_embeddables/types.ts new file mode 100644 index 0000000000000..118b5d340528e --- /dev/null +++ b/src/plugins/presentation_util/public/components/redux_embeddables/types.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 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 { + ActionCreatorWithPayload, + AnyAction, + CaseReducer, + Dispatch, + PayloadAction, +} from '@reduxjs/toolkit'; +import { TypedUseSelectorHook } from 'react-redux'; +import { + EmbeddableInput, + EmbeddableOutput, + IContainer, + IEmbeddable, +} from '../../../../embeddable/public'; + +export interface GenericEmbeddableReducers<InputType> { + /** + * PayloadAction of type any is strategic here because we want to allow payloads of any shape in generic reducers. + * This type will be overridden to remove any and be type safe when returned by ReduxEmbeddableContextServices. + */ + [key: string]: CaseReducer<InputType, PayloadAction<any>>; +} + +export interface ReduxEmbeddableWrapperProps<InputType extends EmbeddableInput = EmbeddableInput> { + embeddable: IEmbeddable<InputType, EmbeddableOutput>; + reducers: GenericEmbeddableReducers<InputType>; + diffInput?: (a: InputType, b: InputType) => Partial<InputType>; +} + +/** + * This context allows components underneath the redux embeddable wrapper to get access to the actions, selector, dispatch, and containerActions. + */ +export interface ReduxEmbeddableContextServices< + InputType extends EmbeddableInput = EmbeddableInput, + ReducerType extends GenericEmbeddableReducers<InputType> = GenericEmbeddableReducers<InputType> +> { + actions: { + [Property in keyof ReducerType]: ActionCreatorWithPayload< + Parameters<ReducerType[Property]>[1]['payload'] + >; + } & { updateEmbeddableReduxState: ActionCreatorWithPayload<Partial<InputType>> }; + useEmbeddableSelector: TypedUseSelectorHook<InputType>; + useEmbeddableDispatch: () => Dispatch<AnyAction>; +} + +export type ReduxContainerContextServices< + InputType extends EmbeddableInput = EmbeddableInput, + ReducerType extends GenericEmbeddableReducers<InputType> = GenericEmbeddableReducers<InputType> +> = ReduxEmbeddableContextServices<InputType, ReducerType> & { + containerActions: Pick< + IContainer, + 'untilEmbeddableLoaded' | 'removeEmbeddable' | 'addNewEmbeddable' | 'updateInputForChild' + >; +}; diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/items/popover.tsx b/src/plugins/presentation_util/public/components/solution_toolbar/items/popover.tsx index 33850005b498b..fea6bf41a1601 100644 --- a/src/plugins/presentation_util/public/components/solution_toolbar/items/popover.tsx +++ b/src/plugins/presentation_util/public/components/solution_toolbar/items/popover.tsx @@ -18,13 +18,17 @@ type AllowedPopoverProps = Omit< 'button' | 'isOpen' | 'closePopover' | 'anchorPosition' >; -export type Props = AllowedButtonProps & AllowedPopoverProps; +export type Props = AllowedButtonProps & + AllowedPopoverProps & { + children: (arg: { closePopover: () => void }) => React.ReactNode; + }; export const SolutionToolbarPopover = ({ label, iconType, primary, iconSide, + children, ...popover }: Props) => { const [isOpen, setIsOpen] = useState(false); @@ -33,10 +37,21 @@ export const SolutionToolbarPopover = ({ const closePopover = () => setIsOpen(false); const button = ( - <SolutionToolbarButton {...{ label, iconType, primary, iconSide }} onClick={onButtonClick} /> + <SolutionToolbarButton + {...{ label, iconType, primary, iconSide }} + onClick={onButtonClick} + data-test-subj={popover['data-test-subj']} + /> ); return ( - <EuiPopover anchorPosition="downLeft" {...{ isOpen, button, closePopover }} {...popover} /> + <EuiPopover + anchorPosition="downLeft" + panelPaddingSize="none" + {...{ isOpen, button, closePopover }} + {...popover} + > + {children({ closePopover })} + </EuiPopover> ); }; diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss index 876ee659b71d7..535570a51d777 100644 --- a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss +++ b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss @@ -8,17 +8,4 @@ border-color: $euiBorderColor !important; } } - - // Temporary fix for two tone icons to make them monochrome - .quickButtonGroup__button--dark { - .euiIcon path { - fill: $euiColorGhost; - } - } - // Temporary fix for two tone icons to make them monochrome - .quickButtonGroup__button--light { - .euiIcon path { - fill: $euiColorInk; - } - } } diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.tsx b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.tsx index eb0a395548cd9..66b22eeb570db 100644 --- a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.tsx +++ b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.tsx @@ -17,27 +17,23 @@ import './quick_group.scss'; export interface QuickButtonProps extends Pick<EuiButtonGroupOptionProps, 'iconType'> { createType: string; onClick: () => void; - isDarkModeEnabled?: boolean; } export interface Props { buttons: QuickButtonProps[]; } -type Option = EuiButtonGroupOptionProps & - Omit<QuickButtonProps, 'createType' | 'isDarkModeEnabled'>; +type Option = EuiButtonGroupOptionProps & Omit<QuickButtonProps, 'createType'>; export const QuickButtonGroup = ({ buttons }: Props) => { const buttonGroupOptions: Option[] = buttons.map((button: QuickButtonProps, index) => { - const { createType: label, isDarkModeEnabled, ...rest } = button; + const { createType: label, ...rest } = button; const title = strings.getAriaButtonLabel(label); return { ...rest, 'aria-label': title, - className: `quickButtonGroup__button ${ - isDarkModeEnabled ? 'quickButtonGroup__button--dark' : 'quickButtonGroup__button--light' - }`, + className: `quickButtonGroup__button`, id: `${htmlIdGenerator()()}${index}`, label, title, diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.stories.tsx b/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.stories.tsx index fa33f53f9ae4f..3a04a4c974538 100644 --- a/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.stories.tsx +++ b/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.stories.tsx @@ -54,29 +54,31 @@ const primaryButtonConfigs = { panelPaddingSize="none" primary={true} > - <EuiContextMenu - initialPanelId={0} - panels={[ - { - id: 0, - title: 'Open editor', - items: [ - { - name: 'Lens', - icon: 'lensApp', - }, - { - name: 'Maps', - icon: 'logoMaps', - }, - { - name: 'TSVB', - icon: 'visVisualBuilder', - }, - ], - }, - ]} - /> + {() => ( + <EuiContextMenu + initialPanelId={0} + panels={[ + { + id: 0, + title: 'Open editor', + items: [ + { + name: 'Lens', + icon: 'lensApp', + }, + { + name: 'Maps', + icon: 'logoMaps', + }, + { + name: 'TSVB', + icon: 'visVisualBuilder', + }, + ], + }, + ]} + /> + )} </SolutionToolbarPopover> ), Dashboard: ( @@ -93,29 +95,31 @@ const extraButtonConfigs = { Canvas: undefined, Dashboard: [ <SolutionToolbarPopover iconType="visualizeApp" label="All editors" panelPaddingSize="none"> - <EuiContextMenu - initialPanelId={0} - panels={[ - { - id: 0, - title: 'Open editor', - items: [ - { - name: 'Lens', - icon: 'lensApp', - }, - { - name: 'Maps', - icon: 'logoMaps', - }, - { - name: 'TSVB', - icon: 'visVisualBuilder', - }, - ], - }, - ]} - /> + {() => ( + <EuiContextMenu + initialPanelId={0} + panels={[ + { + id: 0, + title: 'Open editor', + items: [ + { + name: 'Lens', + icon: 'lensApp', + }, + { + name: 'Maps', + icon: 'logoMaps', + }, + { + name: 'TSVB', + icon: 'visVisualBuilder', + }, + ], + }, + ]} + /> + )} </SolutionToolbarPopover>, ], }; diff --git a/src/plugins/presentation_util/public/mocks.ts b/src/plugins/presentation_util/public/mocks.ts index 91c461646c280..ddb02ce464e22 100644 --- a/src/plugins/presentation_util/public/mocks.ts +++ b/src/plugins/presentation_util/public/mocks.ts @@ -17,6 +17,7 @@ const createStartContract = (coreStart: CoreStart): PresentationUtilPluginStart const startContract: PresentationUtilPluginStart = { ContextProvider: pluginServices.getContextProvider(), labsService: pluginServices.getServices().labs, + controlsService: pluginServices.getServices().controls, }; return startContract; }; diff --git a/src/plugins/presentation_util/public/plugin.ts b/src/plugins/presentation_util/public/plugin.ts index f34bd2f1f8afe..f697f1a29eb82 100644 --- a/src/plugins/presentation_util/public/plugin.ts +++ b/src/plugins/presentation_util/public/plugin.ts @@ -39,6 +39,7 @@ export class PresentationUtilPlugin pluginServices.setRegistry(registry.start({ coreStart, startPlugins })); return { ContextProvider: pluginServices.getContextProvider(), + controlsService: pluginServices.getServices().controls, labsService: pluginServices.getServices().labs, }; } diff --git a/src/plugins/presentation_util/public/services/controls.ts b/src/plugins/presentation_util/public/services/controls.ts new file mode 100644 index 0000000000000..197e986381b10 --- /dev/null +++ b/src/plugins/presentation_util/public/services/controls.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Filter } from '@kbn/es-query'; +import { Query, TimeRange } from '../../../data/public'; +import { + EmbeddableFactory, + EmbeddableInput, + EmbeddableOutput, + IEmbeddable, +} from '../../../embeddable/public'; + +/** + * Control embeddable types + */ +export type InputControlFactory = EmbeddableFactory< + InputControlInput, + InputControlOutput, + InputControlEmbeddable +>; + +export type InputControlInput = EmbeddableInput & { + query?: Query; + filters?: Filter[]; + timeRange?: TimeRange; + twoLineLayout?: boolean; +}; + +export type InputControlOutput = EmbeddableOutput & { + filters?: Filter[]; +}; + +export type InputControlEmbeddable< + TInputControlEmbeddableInput extends InputControlInput = InputControlInput, + TInputControlEmbeddableOutput extends InputControlOutput = InputControlOutput +> = IEmbeddable<TInputControlEmbeddableInput, TInputControlEmbeddableOutput>; + +export interface ControlTypeRegistry { + [key: string]: InputControlFactory; +} + +export interface PresentationControlsService { + registerInputControlType: (factory: InputControlFactory) => void; + + getControlFactory: < + I extends InputControlInput = InputControlInput, + O extends InputControlOutput = InputControlOutput, + E extends InputControlEmbeddable<I, O> = InputControlEmbeddable<I, O> + >( + type: string + ) => EmbeddableFactory<I, O, E>; + + getInputControlTypes: () => string[]; +} + +export const getCommonControlsService = () => { + const controlsFactoriesMap: ControlTypeRegistry = {}; + + const registerInputControlType = (factory: InputControlFactory) => { + controlsFactoriesMap[factory.type] = factory; + }; + + const getControlFactory = < + I extends InputControlInput = InputControlInput, + O extends InputControlOutput = InputControlOutput, + E extends InputControlEmbeddable<I, O> = InputControlEmbeddable<I, O> + >( + type: string + ) => { + return controlsFactoriesMap[type] as EmbeddableFactory<I, O, E>; + }; + + const getInputControlTypes = () => Object.keys(controlsFactoriesMap); + + return { + registerInputControlType, + getControlFactory, + getInputControlTypes, + }; +}; diff --git a/src/plugins/presentation_util/public/services/index.ts b/src/plugins/presentation_util/public/services/index.ts index c622ad82bb888..21012971ca86d 100644 --- a/src/plugins/presentation_util/public/services/index.ts +++ b/src/plugins/presentation_util/public/services/index.ts @@ -13,6 +13,7 @@ import { PresentationDashboardsService } from './dashboards'; import { PresentationLabsService } from './labs'; import { registry as stubRegistry } from './stub'; import { PresentationOverlaysService } from './overlays'; +import { PresentationControlsService } from './controls'; export { PresentationCapabilitiesService } from './capabilities'; export { PresentationDashboardsService } from './dashboards'; @@ -21,6 +22,7 @@ export interface PresentationUtilServices { dashboards: PresentationDashboardsService; capabilities: PresentationCapabilitiesService; overlays: PresentationOverlaysService; + controls: PresentationControlsService; labs: PresentationLabsService; } @@ -31,5 +33,6 @@ export const getStubPluginServices = (): PresentationUtilPluginStart => { return { ContextProvider: pluginServices.getContextProvider(), labsService: pluginServices.getServices().labs, + controlsService: pluginServices.getServices().controls, }; }; diff --git a/src/plugins/apm_oss/public/types.ts b/src/plugins/presentation_util/public/services/kibana/controls.ts similarity index 52% rename from src/plugins/apm_oss/public/types.ts rename to src/plugins/presentation_util/public/services/kibana/controls.ts index 16a1fe8be8004..e5dc84a3dd645 100644 --- a/src/plugins/apm_oss/public/types.ts +++ b/src/plugins/presentation_util/public/services/kibana/controls.ts @@ -6,11 +6,8 @@ * Side Public License, v 1. */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ApmOssPluginSetup {} +import { PluginServiceFactory } from '../create'; +import { getCommonControlsService, PresentationControlsService } from '../controls'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ApmOssPluginStart {} - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface AppPluginStartDependencies {} +export type ControlsServiceFactory = PluginServiceFactory<PresentationControlsService>; +export const controlsServiceFactory = () => getCommonControlsService(); diff --git a/src/plugins/presentation_util/public/services/kibana/index.ts b/src/plugins/presentation_util/public/services/kibana/index.ts index 8a9a28606f24b..48c921bff1efd 100644 --- a/src/plugins/presentation_util/public/services/kibana/index.ts +++ b/src/plugins/presentation_util/public/services/kibana/index.ts @@ -18,6 +18,7 @@ import { } from '../create'; import { PresentationUtilPluginStartDeps } from '../../types'; import { PresentationUtilServices } from '..'; +import { controlsServiceFactory } from './controls'; export { capabilitiesServiceFactory } from './capabilities'; export { dashboardsServiceFactory } from './dashboards'; @@ -32,6 +33,7 @@ export const providers: PluginServiceProviders< labs: new PluginServiceProvider(labsServiceFactory), dashboards: new PluginServiceProvider(dashboardsServiceFactory), overlays: new PluginServiceProvider(overlaysServiceFactory), + controls: new PluginServiceProvider(controlsServiceFactory), }; export const registry = new PluginServiceRegistry< diff --git a/src/plugins/presentation_util/public/services/storybook/controls.ts b/src/plugins/presentation_util/public/services/storybook/controls.ts new file mode 100644 index 0000000000000..e5dc84a3dd645 --- /dev/null +++ b/src/plugins/presentation_util/public/services/storybook/controls.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PluginServiceFactory } from '../create'; +import { getCommonControlsService, PresentationControlsService } from '../controls'; + +export type ControlsServiceFactory = PluginServiceFactory<PresentationControlsService>; +export const controlsServiceFactory = () => getCommonControlsService(); diff --git a/src/plugins/presentation_util/public/services/storybook/index.ts b/src/plugins/presentation_util/public/services/storybook/index.ts index 1ce1eb72848c9..9de4934d51300 100644 --- a/src/plugins/presentation_util/public/services/storybook/index.ts +++ b/src/plugins/presentation_util/public/services/storybook/index.ts @@ -6,12 +6,18 @@ * Side Public License, v 1. */ -import { PluginServices, PluginServiceProviders, PluginServiceProvider } from '../create'; +import { + PluginServices, + PluginServiceProviders, + PluginServiceProvider, + PluginServiceRegistry, +} from '../create'; import { dashboardsServiceFactory } from '../stub/dashboards'; import { labsServiceFactory } from './labs'; import { capabilitiesServiceFactory } from './capabilities'; import { PresentationUtilServices } from '..'; import { overlaysServiceFactory } from './overlays'; +import { controlsServiceFactory } from './controls'; export { PluginServiceProviders, PluginServiceProvider, PluginServiceRegistry } from '../create'; export { PresentationUtilServices } from '..'; @@ -27,7 +33,10 @@ export const providers: PluginServiceProviders<PresentationUtilServices, Storybo capabilities: new PluginServiceProvider(capabilitiesServiceFactory), dashboards: new PluginServiceProvider(dashboardsServiceFactory), overlays: new PluginServiceProvider(overlaysServiceFactory), + controls: new PluginServiceProvider(controlsServiceFactory), labs: new PluginServiceProvider(labsServiceFactory), }; export const pluginServices = new PluginServices<PresentationUtilServices>(); + +export const registry = new PluginServiceRegistry<PresentationUtilServices>(providers); diff --git a/src/plugins/presentation_util/public/services/stub/controls.ts b/src/plugins/presentation_util/public/services/stub/controls.ts new file mode 100644 index 0000000000000..e5dc84a3dd645 --- /dev/null +++ b/src/plugins/presentation_util/public/services/stub/controls.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PluginServiceFactory } from '../create'; +import { getCommonControlsService, PresentationControlsService } from '../controls'; + +export type ControlsServiceFactory = PluginServiceFactory<PresentationControlsService>; +export const controlsServiceFactory = () => getCommonControlsService(); diff --git a/src/plugins/presentation_util/public/services/stub/index.ts b/src/plugins/presentation_util/public/services/stub/index.ts index 61dca47427531..35aabdb465b14 100644 --- a/src/plugins/presentation_util/public/services/stub/index.ts +++ b/src/plugins/presentation_util/public/services/stub/index.ts @@ -12,7 +12,7 @@ import { labsServiceFactory } from './labs'; import { PluginServiceProviders, PluginServiceProvider, PluginServiceRegistry } from '../create'; import { PresentationUtilServices } from '..'; import { overlaysServiceFactory } from './overlays'; - +import { controlsServiceFactory } from './controls'; export { dashboardsServiceFactory } from './dashboards'; export { capabilitiesServiceFactory } from './capabilities'; @@ -20,6 +20,7 @@ export const providers: PluginServiceProviders<PresentationUtilServices> = { dashboards: new PluginServiceProvider(dashboardsServiceFactory), capabilities: new PluginServiceProvider(capabilitiesServiceFactory), overlays: new PluginServiceProvider(overlaysServiceFactory), + controls: new PluginServiceProvider(controlsServiceFactory), labs: new PluginServiceProvider(labsServiceFactory), }; diff --git a/src/plugins/presentation_util/public/types.ts b/src/plugins/presentation_util/public/types.ts index 05779ffb206c4..3903d1bc2786e 100644 --- a/src/plugins/presentation_util/public/types.ts +++ b/src/plugins/presentation_util/public/types.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { PresentationControlsService } from './services/controls'; import { PresentationLabsService } from './services/labs'; // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -14,6 +15,7 @@ export interface PresentationUtilPluginSetup {} export interface PresentationUtilPluginStart { ContextProvider: React.FC; labsService: PresentationLabsService; + controlsService: PresentationControlsService; } // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/table.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/table.test.tsx.snap index 8325e7dc886e8..bca54ff67591c 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/table.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/table.test.tsx.snap @@ -188,7 +188,12 @@ exports[`Table prevents saved objects from being deleted 1`] = ` ] } loading={false} - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } onChange={[Function]} pagination={ Object { @@ -403,7 +408,12 @@ exports[`Table should render normally 1`] = ` ] } loading={false} - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } onChange={[Function]} pagination={ Object { diff --git a/src/plugins/share/common/url_service/__tests__/setup.ts b/src/plugins/share/common/url_service/__tests__/setup.ts index 239b2554e663a..8f339c2060faf 100644 --- a/src/plugins/share/common/url_service/__tests__/setup.ts +++ b/src/plugins/share/common/url_service/__tests__/setup.ts @@ -37,7 +37,7 @@ export const urlServiceTestSetup = (partialDeps: Partial<UrlServiceDependencies> getUrl: async () => { throw new Error('not implemented'); }, - shortUrls: { + shortUrls: () => ({ get: () => ({ create: async () => { throw new Error('Not implemented.'); @@ -52,7 +52,7 @@ export const urlServiceTestSetup = (partialDeps: Partial<UrlServiceDependencies> throw new Error('Not implemented.'); }, }), - }, + }), ...partialDeps, }; const service = new UrlService(deps); diff --git a/src/plugins/share/common/url_service/locators/locator.ts b/src/plugins/share/common/url_service/locators/locator.ts index fc970e2c7a490..2d33f701df595 100644 --- a/src/plugins/share/common/url_service/locators/locator.ts +++ b/src/plugins/share/common/url_service/locators/locator.ts @@ -67,13 +67,15 @@ export class Locator<P extends SerializableRecord> implements LocatorPublic<P> { state: P, references: SavedObjectReference[] ): P => { - return this.definition.inject ? this.definition.inject(state, references) : state; + if (!this.definition.inject) return state; + return this.definition.inject(state, references); }; public readonly extract: PersistableState<P>['extract'] = ( state: P ): { state: P; references: SavedObjectReference[] } => { - return this.definition.extract ? this.definition.extract(state) : { state, references: [] }; + if (!this.definition.extract) return { state, references: [] }; + return this.definition.extract(state); }; // LocatorPublic<P> ---------------------------------------------------------- diff --git a/src/plugins/share/common/url_service/locators/locator_client.ts b/src/plugins/share/common/url_service/locators/locator_client.ts index 587083551aa6d..7dd69165be5dd 100644 --- a/src/plugins/share/common/url_service/locators/locator_client.ts +++ b/src/plugins/share/common/url_service/locators/locator_client.ts @@ -7,9 +7,12 @@ */ import type { SerializableRecord } from '@kbn/utility-types'; +import { MigrateFunctionsObject } from 'src/plugins/kibana_utils/common'; +import { SavedObjectReference } from 'kibana/server'; import type { LocatorDependencies } from './locator'; -import type { LocatorDefinition, LocatorPublic, ILocatorClient } from './types'; +import type { LocatorDefinition, LocatorPublic, ILocatorClient, LocatorData } from './types'; import { Locator } from './locator'; +import { LocatorMigrationFunction, LocatorsMigrationMap } from '.'; export type LocatorClientDependencies = LocatorDependencies; @@ -44,4 +47,91 @@ export class LocatorClient implements ILocatorClient { public get<P extends SerializableRecord>(id: string): undefined | LocatorPublic<P> { return this.locators.get(id); } + + protected getOrThrow<P extends SerializableRecord>(id: string): LocatorPublic<P> { + const locator = this.locators.get(id); + if (!locator) throw new Error(`Locator [ID = "${id}"] is not registered.`); + return locator; + } + + public migrations(): { [locatorId: string]: MigrateFunctionsObject } { + const migrations: { [locatorId: string]: MigrateFunctionsObject } = {}; + + for (const locator of this.locators.values()) { + migrations[locator.id] = locator.migrations; + } + + return migrations; + } + + // PersistableStateService<LocatorData> ---------------------------------------------------------- + + public telemetry( + state: LocatorData, + collector: Record<string, unknown> + ): Record<string, unknown> { + for (const locator of this.locators.values()) { + collector = locator.telemetry(state.state, collector); + } + + return collector; + } + + public inject(state: LocatorData, references: SavedObjectReference[]): LocatorData { + const locator = this.getOrThrow(state.id); + const filteredReferences = references + .filter((ref) => ref.name.startsWith('params:')) + .map((ref) => ({ + ...ref, + name: ref.name.substr('params:'.length), + })); + return { + ...state, + state: locator.inject(state.state, filteredReferences), + }; + } + + public extract(state: LocatorData): { state: LocatorData; references: SavedObjectReference[] } { + const locator = this.getOrThrow(state.id); + const extracted = locator.extract(state.state); + return { + state: { + ...state, + state: extracted.state, + }, + references: extracted.references.map((ref) => ({ + ...ref, + name: 'params:' + ref.name, + })), + }; + } + + public readonly getAllMigrations = (): LocatorsMigrationMap => { + const locatorParamsMigrations = this.migrations(); + const locatorMigrations: LocatorsMigrationMap = {}; + const versions = new Set<string>(); + + for (const migrationMap of Object.values(locatorParamsMigrations)) + for (const version of Object.keys(migrationMap)) versions.add(version); + + for (const version of versions.values()) { + const migration: LocatorMigrationFunction = (locator) => { + const locatorMigrationsMap = locatorParamsMigrations[locator.id]; + if (!locatorMigrationsMap) return locator; + + const migrationFunction = locatorMigrationsMap[version]; + if (!migrationFunction) return locator; + + return { + ...locator, + version, + state: migrationFunction(locator.state), + }; + }; + + locatorMigrations[version] = migration; + } + + return locatorMigrations; + }; } diff --git a/src/plugins/share/common/url_service/locators/types.ts b/src/plugins/share/common/url_service/locators/types.ts index ab0efa9b2375a..c64dc588aaf22 100644 --- a/src/plugins/share/common/url_service/locators/types.ts +++ b/src/plugins/share/common/url_service/locators/types.ts @@ -8,13 +8,18 @@ import type { SerializableRecord } from '@kbn/utility-types'; import { DependencyList } from 'react'; -import { PersistableState } from 'src/plugins/kibana_utils/common'; +import { + MigrateFunction, + PersistableState, + PersistableStateService, + VersionedState, +} from 'src/plugins/kibana_utils/common'; import type { FormatSearchParamsOptions } from './redirect'; /** * URL locator registry. */ -export interface ILocatorClient { +export interface ILocatorClient extends PersistableStateService<LocatorData> { /** * Create and register a new locator. * @@ -141,3 +146,22 @@ export interface KibanaLocation<S = object> { */ state: S; } + +/** + * Represents a serializable state of a locator. Includes locator ID, version + * and its params. + */ +export interface LocatorData<LocatorParams extends SerializableRecord = SerializableRecord> + extends VersionedState<LocatorParams>, + SerializableRecord { + /** + * Locator ID. + */ + id: string; +} + +export interface LocatorsMigrationMap { + [semver: string]: LocatorMigrationFunction; +} + +export type LocatorMigrationFunction = MigrateFunction<LocatorData, LocatorData>; diff --git a/src/plugins/share/common/url_service/mocks.ts b/src/plugins/share/common/url_service/mocks.ts index dd86e2398589e..24ba226818427 100644 --- a/src/plugins/share/common/url_service/mocks.ts +++ b/src/plugins/share/common/url_service/mocks.ts @@ -18,7 +18,7 @@ export class MockUrlService extends UrlService { getUrl: async ({ app, path }, { absolute }) => { return `${absolute ? 'http://localhost:8888' : ''}/app/${app}${path}`; }, - shortUrls: { + shortUrls: () => ({ get: () => ({ create: async () => { throw new Error('Not implemented.'); @@ -33,7 +33,7 @@ export class MockUrlService extends UrlService { throw new Error('Not implemented.'); }, }), - }, + }), }); } } diff --git a/src/plugins/share/common/url_service/short_urls/types.ts b/src/plugins/share/common/url_service/short_urls/types.ts index db744a25f9f79..698ffe7b8421b 100644 --- a/src/plugins/share/common/url_service/short_urls/types.ts +++ b/src/plugins/share/common/url_service/short_urls/types.ts @@ -6,9 +6,8 @@ * Side Public License, v 1. */ -import { SerializableRecord } from '@kbn/utility-types'; -import { VersionedState } from 'src/plugins/kibana_utils/common'; -import { LocatorPublic } from '../locators'; +import type { SerializableRecord } from '@kbn/utility-types'; +import type { LocatorPublic, ILocatorClient, LocatorData } from '../locators'; /** * A factory for Short URL Service. We need this factory as the dependency @@ -21,6 +20,10 @@ export interface IShortUrlClientFactory<D> { get(dependencies: D): IShortUrlClient; } +export type IShortUrlClientFactoryProvider<D> = (params: { + locators: ILocatorClient; +}) => IShortUrlClientFactory<D>; + /** * CRUD-like API for short URLs. */ @@ -128,14 +131,4 @@ export interface ShortUrlData<LocatorParams extends SerializableRecord = Seriali readonly locator: LocatorData<LocatorParams>; } -/** - * Represents a serializable state of a locator. Includes locator ID, version - * and its params. - */ -export interface LocatorData<LocatorParams extends SerializableRecord = SerializableRecord> - extends VersionedState<LocatorParams> { - /** - * Locator ID. - */ - id: string; -} +export type { LocatorData }; diff --git a/src/plugins/share/common/url_service/url_service.ts b/src/plugins/share/common/url_service/url_service.ts index dedb81720865d..24e2ea0b62379 100644 --- a/src/plugins/share/common/url_service/url_service.ts +++ b/src/plugins/share/common/url_service/url_service.ts @@ -7,10 +7,10 @@ */ import { LocatorClient, LocatorClientDependencies } from './locators'; -import { IShortUrlClientFactory } from './short_urls'; +import { IShortUrlClientFactoryProvider, IShortUrlClientFactory } from './short_urls'; export interface UrlServiceDependencies<D = unknown> extends LocatorClientDependencies { - shortUrls: IShortUrlClientFactory<D>; + shortUrls: IShortUrlClientFactoryProvider<D>; } /** @@ -26,6 +26,8 @@ export class UrlService<D = unknown> { constructor(protected readonly deps: UrlServiceDependencies<D>) { this.locators = new LocatorClient(deps); - this.shortUrls = deps.shortUrls; + this.shortUrls = deps.shortUrls({ + locators: this.locators, + }); } } diff --git a/src/plugins/share/public/mocks.ts b/src/plugins/share/public/mocks.ts index 73df7257290f0..33cdf141de9f3 100644 --- a/src/plugins/share/public/mocks.ts +++ b/src/plugins/share/public/mocks.ts @@ -18,7 +18,7 @@ const url = new UrlService({ getUrl: async ({ app, path }, { absolute }) => { return `${absolute ? 'http://localhost:8888' : ''}/app/${app}${path}`; }, - shortUrls: { + shortUrls: () => ({ get: () => ({ create: async () => { throw new Error('Not implemented'); @@ -33,7 +33,7 @@ const url = new UrlService({ throw new Error('Not implemented.'); }, }), - }, + }), }); const createSetupContract = (): Setup => { diff --git a/src/plugins/share/public/plugin.ts b/src/plugins/share/public/plugin.ts index 103fbb50bb95f..fd8a5fd7541a6 100644 --- a/src/plugins/share/public/plugin.ts +++ b/src/plugins/share/public/plugin.ts @@ -104,7 +104,7 @@ export class SharePlugin implements Plugin<SharePluginSetup, SharePluginStart> { }); return url; }, - shortUrls: { + shortUrls: () => ({ get: () => ({ create: async () => { throw new Error('Not implemented'); @@ -119,7 +119,7 @@ export class SharePlugin implements Plugin<SharePluginSetup, SharePluginStart> { throw new Error('Not implemented.'); }, }), - }, + }), }); this.url.locators.create(new LegacyShortUrlLocatorDefinition()); diff --git a/src/plugins/share/server/plugin.ts b/src/plugins/share/server/plugin.ts index f0e4abf9eb589..d79588420fe87 100644 --- a/src/plugins/share/server/plugin.ts +++ b/src/plugins/share/server/plugin.ts @@ -9,11 +9,14 @@ import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server'; -import { url } from './saved_objects'; import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../common/constants'; import { UrlService } from '../common/url_service'; -import { ServerUrlService, ServerShortUrlClientFactory } from './url_service'; -import { registerUrlServiceRoutes } from './url_service/http/register_url_service_routes'; +import { + ServerUrlService, + ServerShortUrlClientFactory, + registerUrlServiceRoutes, + registerUrlServiceSavedObjectType, +} from './url_service'; import { LegacyShortUrlLocatorDefinition } from '../common/url_service/locators/legacy_short_url_locator'; /** @public */ @@ -44,18 +47,17 @@ export class SharePlugin implements Plugin<SharePluginSetup, SharePluginStart> { getUrl: async () => { throw new Error('Locator .getUrl() currently is not supported on the server.'); }, - shortUrls: new ServerShortUrlClientFactory({ - currentVersion: this.version, - }), + shortUrls: ({ locators }) => + new ServerShortUrlClientFactory({ + currentVersion: this.version, + locators, + }), }); - this.url.locators.create(new LegacyShortUrlLocatorDefinition()); - const router = core.http.createRouter(); - - registerUrlServiceRoutes(core, router, this.url); + registerUrlServiceSavedObjectType(core.savedObjects, this.url); + registerUrlServiceRoutes(core, core.http.createRouter(), this.url); - core.savedObjects.registerType(url); core.uiSettings.register({ [CSV_SEPARATOR_SETTING]: { name: i18n.translate('share.advancedSettings.csv.separatorTitle', { diff --git a/src/plugins/share/server/saved_objects/url.ts b/src/plugins/share/server/saved_objects/url.ts deleted file mode 100644 index 6288e87f629f5..0000000000000 --- a/src/plugins/share/server/saved_objects/url.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 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 { SavedObjectsType } from 'kibana/server'; - -export const url: SavedObjectsType = { - name: 'url', - namespaceType: 'single', - hidden: false, - management: { - icon: 'link', - defaultSearchField: 'url', - importableAndExportable: true, - getTitle(obj) { - return `/goto/${encodeURIComponent(obj.id)}`; - }, - getInAppUrl(obj) { - return { - path: '/goto/' + encodeURIComponent(obj.id), - uiCapabilitiesPath: '', - }; - }, - }, - mappings: { - properties: { - slug: { - type: 'text', - fields: { - keyword: { - type: 'keyword', - }, - }, - }, - accessCount: { - type: 'long', - }, - accessDate: { - type: 'date', - }, - createDate: { - type: 'date', - }, - // Legacy field - contains already pre-formatted final URL. - // This is here to support old saved objects that have this field. - // TODO: Remove this field and execute a migration to the new format. - url: { - type: 'text', - fields: { - keyword: { - type: 'keyword', - ignore_above: 2048, - }, - }, - }, - // Information needed to load and execute a locator. - locatorJSON: { - type: 'text', - index: false, - }, - }, - }, -}; diff --git a/src/plugins/share/server/url_service/index.ts b/src/plugins/share/server/url_service/index.ts index 068a5289d42ed..62d1329371736 100644 --- a/src/plugins/share/server/url_service/index.ts +++ b/src/plugins/share/server/url_service/index.ts @@ -8,3 +8,5 @@ export * from './types'; export * from './short_urls'; +export { registerUrlServiceRoutes } from './http/register_url_service_routes'; +export { registerUrlServiceSavedObjectType } from './saved_objects/register_url_service_saved_object_type'; diff --git a/src/plugins/share/server/url_service/saved_objects/register_url_service_saved_object_type.test.ts b/src/plugins/share/server/url_service/saved_objects/register_url_service_saved_object_type.test.ts new file mode 100644 index 0000000000000..651169f6101a9 --- /dev/null +++ b/src/plugins/share/server/url_service/saved_objects/register_url_service_saved_object_type.test.ts @@ -0,0 +1,144 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { SerializableRecord } from '@kbn/utility-types'; +import type { + SavedObjectMigrationMap, + SavedObjectsType, + SavedObjectUnsanitizedDoc, +} from 'kibana/server'; +import { ServerShortUrlClientFactory } from '..'; +import { UrlService, LocatorDefinition } from '../../../common/url_service'; +import { LegacyShortUrlLocatorDefinition } from '../../../common/url_service/locators/legacy_short_url_locator'; +import { MemoryShortUrlStorage } from '../short_urls/storage/memory_short_url_storage'; +import { ShortUrlSavedObjectAttributes } from '../short_urls/storage/saved_object_short_url_storage'; +import { registerUrlServiceSavedObjectType } from './register_url_service_saved_object_type'; + +const setup = () => { + const currentVersion = '7.7.7'; + const service = new UrlService({ + getUrl: () => { + throw new Error('Not implemented.'); + }, + navigate: () => { + throw new Error('Not implemented.'); + }, + shortUrls: ({ locators }) => + new ServerShortUrlClientFactory({ + currentVersion, + locators, + }), + }); + const definition = new LegacyShortUrlLocatorDefinition(); + const locator = service.locators.create(definition); + const storage = new MemoryShortUrlStorage(); + const client = service.shortUrls.get({ storage }); + + let type: SavedObjectsType; + registerUrlServiceSavedObjectType( + { + registerType: (urlSavedObjectType) => { + type = urlSavedObjectType; + }, + }, + service + ); + + return { + type: type!, + client, + service, + storage, + locator, + definition, + currentVersion, + }; +}; + +describe('migrations', () => { + test('returns empty migrations object if there are no migrations', () => { + const { type } = setup(); + + expect((type.migrations as () => SavedObjectMigrationMap)()).toEqual({}); + }); + + test('migrates locator to the latest version', () => { + interface FooLocatorParamsOld extends SerializableRecord { + color: string; + indexPattern: string; + } + + interface FooLocatorParams extends SerializableRecord { + color: string; + indexPatterns: string[]; + } + + class FooLocatorDefinition implements LocatorDefinition<FooLocatorParams> { + public readonly id = 'FOO_LOCATOR'; + + public async getLocation() { + return { + app: 'foo', + path: '', + state: {}, + }; + } + + migrations = { + '8.0.0': ({ indexPattern, ...rest }: FooLocatorParamsOld): FooLocatorParams => ({ + ...rest, + indexPatterns: [indexPattern], + }), + }; + } + + const { type, service } = setup(); + + service.locators.create(new FooLocatorDefinition()); + + const migrationFunction = (type.migrations as () => SavedObjectMigrationMap)()['8.0.0']; + + expect(typeof migrationFunction).toBe('function'); + + const doc1: SavedObjectUnsanitizedDoc<ShortUrlSavedObjectAttributes> = { + id: 'foo', + attributes: { + accessCount: 0, + accessDate: 0, + createDate: 0, + locatorJSON: JSON.stringify({ + id: 'FOO_LOCATOR', + version: '7.7.7', + state: { + color: 'red', + indexPattern: 'myIndex', + }, + }), + url: '', + }, + type: 'url', + }; + + const doc2 = migrationFunction(doc1, {} as any); + + expect(doc2.id).toBe('foo'); + expect(doc2.type).toBe('url'); + expect(doc2.attributes.accessCount).toBe(0); + expect(doc2.attributes.accessDate).toBe(0); + expect(doc2.attributes.createDate).toBe(0); + expect(doc2.attributes.url).toBe(''); + expect(JSON.parse(doc2.attributes.locatorJSON)).toEqual({ + id: 'FOO_LOCATOR', + version: '8.0.0', + state: { + color: 'red', + indexPatterns: ['myIndex'], + }, + }); + }); +}); diff --git a/src/plugins/share/server/url_service/saved_objects/register_url_service_saved_object_type.ts b/src/plugins/share/server/url_service/saved_objects/register_url_service_saved_object_type.ts new file mode 100644 index 0000000000000..b2fcefcc767cf --- /dev/null +++ b/src/plugins/share/server/url_service/saved_objects/register_url_service_saved_object_type.ts @@ -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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { + SavedObjectMigrationMap, + SavedObjectsServiceSetup, + SavedObjectsType, +} from 'kibana/server'; +import type { LocatorData } from 'src/plugins/share/common/url_service'; +import type { ServerUrlService } from '..'; + +export const registerUrlServiceSavedObjectType = ( + so: Pick<SavedObjectsServiceSetup, 'registerType'>, + service: ServerUrlService +) => { + const urlSavedObjectType: SavedObjectsType = { + name: 'url', + namespaceType: 'single', + hidden: false, + management: { + icon: 'link', + defaultSearchField: 'url', + importableAndExportable: true, + getTitle(obj) { + return `/goto/${encodeURIComponent(obj.id)}`; + }, + getInAppUrl(obj) { + return { + path: '/goto/' + encodeURIComponent(obj.id), + uiCapabilitiesPath: '', + }; + }, + }, + mappings: { + properties: { + slug: { + type: 'text', + fields: { + keyword: { + type: 'keyword', + }, + }, + }, + accessCount: { + type: 'long', + }, + accessDate: { + type: 'date', + }, + createDate: { + type: 'date', + }, + // Legacy field - contains already pre-formatted final URL. + // This is here to support old saved objects that have this field. + // TODO: Remove this field and execute a migration to the new format. + url: { + type: 'text', + fields: { + keyword: { + type: 'keyword', + ignore_above: 2048, + }, + }, + }, + // Information needed to load and execute a locator. + locatorJSON: { + type: 'text', + index: false, + }, + }, + }, + migrations: () => { + const locatorMigrations = service.locators.getAllMigrations(); + const savedObjectLocatorMigrations: SavedObjectMigrationMap = {}; + + for (const [version, locatorMigration] of Object.entries(locatorMigrations)) { + savedObjectLocatorMigrations[version] = (doc) => { + const locator = JSON.parse(doc.attributes.locatorJSON) as LocatorData; + doc.attributes = { + ...doc.attributes, + locatorJSON: JSON.stringify(locatorMigration(locator)), + }; + return doc; + }; + } + + return savedObjectLocatorMigrations; + }, + }; + + so.registerType(urlSavedObjectType); +}; diff --git a/src/plugins/share/server/url_service/short_urls/short_url_client.test.ts b/src/plugins/share/server/url_service/short_urls/short_url_client.test.ts index ac684eb03a9d5..503748a2b1cad 100644 --- a/src/plugins/share/server/url_service/short_urls/short_url_client.test.ts +++ b/src/plugins/share/server/url_service/short_urls/short_url_client.test.ts @@ -7,9 +7,11 @@ */ import { ServerShortUrlClientFactory } from './short_url_client_factory'; -import { UrlService } from '../../../common/url_service'; +import { UrlService, LocatorDefinition } from '../../../common/url_service'; import { LegacyShortUrlLocatorDefinition } from '../../../common/url_service/locators/legacy_short_url_locator'; import { MemoryShortUrlStorage } from './storage/memory_short_url_storage'; +import { SerializableRecord } from '@kbn/utility-types'; +import { SavedObjectReference } from 'kibana/server'; const setup = () => { const currentVersion = '1.2.3'; @@ -20,9 +22,11 @@ const setup = () => { navigate: () => { throw new Error('Not implemented.'); }, - shortUrls: new ServerShortUrlClientFactory({ - currentVersion, - }), + shortUrls: ({ locators }) => + new ServerShortUrlClientFactory({ + currentVersion, + locators, + }), }); const definition = new LegacyShortUrlLocatorDefinition(); const locator = service.locators.create(definition); @@ -177,4 +181,111 @@ describe('ServerShortUrlClient', () => { ); }); }); + + describe('Persistable State', () => { + interface FooLocatorParams extends SerializableRecord { + dashboardId: string; + indexPatternId: string; + } + + class FooLocatorDefinition implements LocatorDefinition<FooLocatorParams> { + public readonly id = 'FOO_LOCATOR'; + + public readonly getLocation = async () => ({ + app: 'foo_app', + path: '/foo/path', + state: {}, + }); + + public readonly extract = ( + state: FooLocatorParams + ): { state: FooLocatorParams; references: SavedObjectReference[] } => ({ + state, + references: [ + { + id: state.dashboardId, + type: 'dashboard', + name: 'dashboardId', + }, + { + id: state.indexPatternId, + type: 'index_pattern', + name: 'indexPatternId', + }, + ], + }); + + public readonly inject = ( + state: FooLocatorParams, + references: SavedObjectReference[] + ): FooLocatorParams => { + const dashboard = references.find( + (ref) => ref.type === 'dashboard' && ref.name === 'dashboardId' + ); + const indexPattern = references.find( + (ref) => ref.type === 'index_pattern' && ref.name === 'indexPatternId' + ); + + return { + ...state, + dashboardId: dashboard ? dashboard.id : '', + indexPatternId: indexPattern ? indexPattern.id : '', + }; + }; + } + + test('extracts and persists references', async () => { + const { service, client, storage } = setup(); + const locator = service.locators.create(new FooLocatorDefinition()); + const shortUrl = await client.create({ + locator, + params: { + dashboardId: '123', + indexPatternId: '456', + }, + }); + const record = await storage.getById(shortUrl.data.id); + + expect(record.references).toEqual([ + { + id: '123', + type: 'dashboard', + name: 'locator:params:dashboardId', + }, + { + id: '456', + type: 'index_pattern', + name: 'locator:params:indexPatternId', + }, + ]); + }); + + test('injects references', async () => { + const { service, client, storage } = setup(); + const locator = service.locators.create(new FooLocatorDefinition()); + const shortUrl1 = await client.create({ + locator, + params: { + dashboardId: '3', + indexPatternId: '5', + }, + }); + const record1 = await storage.getById(shortUrl1.data.id); + + record1.data.locator.state = {}; + + await storage.update(record1.data.id, record1.data); + + const record2 = await storage.getById(shortUrl1.data.id); + + expect(record2.data.locator.state).toEqual({}); + + const shortUrl2 = await client.get(shortUrl1.data.id); + + expect(shortUrl2.data.locator.state).toEqual({ + dashboardId: '3', + indexPatternId: '5', + }); + }); + }); }); diff --git a/src/plugins/share/server/url_service/short_urls/short_url_client.ts b/src/plugins/share/server/url_service/short_urls/short_url_client.ts index caaa76bef172d..1efece073d955 100644 --- a/src/plugins/share/server/url_service/short_urls/short_url_client.ts +++ b/src/plugins/share/server/url_service/short_urls/short_url_client.ts @@ -7,8 +7,17 @@ */ import type { SerializableRecord } from '@kbn/utility-types'; +import { SavedObjectReference } from 'kibana/server'; import { generateSlug } from 'random-word-slugs'; -import type { IShortUrlClient, ShortUrl, ShortUrlCreateParams } from '../../../common/url_service'; +import { ShortUrlRecord } from '.'; +import type { + IShortUrlClient, + ShortUrl, + ShortUrlCreateParams, + ILocatorClient, + ShortUrlData, + LocatorData, +} from '../../../common/url_service'; import type { ShortUrlStorage } from './types'; import { validateSlug } from './util'; @@ -36,6 +45,11 @@ export interface ServerShortUrlClientDependencies { * Storage provider for short URLs. */ storage: ShortUrlStorage; + + /** + * The locators service. + */ + locators: ILocatorClient; } export class ServerShortUrlClient implements IShortUrlClient { @@ -64,44 +78,80 @@ export class ServerShortUrlClient implements IShortUrlClient { } } + const extracted = this.extractReferences({ + id: locator.id, + version: currentVersion, + state: params, + }); const now = Date.now(); - const data = await storage.create({ - accessCount: 0, - accessDate: now, - createDate: now, - slug, - locator: { - id: locator.id, - version: currentVersion, - state: params, + + const data = await storage.create<P>( + { + accessCount: 0, + accessDate: now, + createDate: now, + slug, + locator: extracted.state as LocatorData<P>, }, - }); + { references: extracted.references } + ); return { data, }; } - public async get(id: string): Promise<ShortUrl> { - const { storage } = this.dependencies; - const data = await storage.getById(id); + private extractReferences(locatorData: LocatorData): { + state: LocatorData; + references: SavedObjectReference[]; + } { + const { locators } = this.dependencies; + const { state, references } = locators.extract(locatorData); + return { + state, + references: references.map((ref) => ({ + ...ref, + name: 'locator:' + ref.name, + })), + }; + } + private injectReferences({ data, references }: ShortUrlRecord): ShortUrlData { + const { locators } = this.dependencies; + const locatorReferences = references + .filter((ref) => ref.name.startsWith('locator:')) + .map((ref) => ({ + ...ref, + name: ref.name.substr('locator:'.length), + })); return { - data, + ...data, + locator: locators.inject(data.locator, locatorReferences), }; } - public async delete(id: string): Promise<void> { + public async get(id: string): Promise<ShortUrl> { const { storage } = this.dependencies; - await storage.delete(id); + const record = await storage.getById(id); + const data = this.injectReferences(record); + + return { + data, + }; } public async resolve(slug: string): Promise<ShortUrl> { const { storage } = this.dependencies; - const data = await storage.getBySlug(slug); + const record = await storage.getBySlug(slug); + const data = this.injectReferences(record); return { data, }; } + + public async delete(id: string): Promise<void> { + const { storage } = this.dependencies; + await storage.delete(id); + } } diff --git a/src/plugins/share/server/url_service/short_urls/short_url_client_factory.ts b/src/plugins/share/server/url_service/short_urls/short_url_client_factory.ts index 696233b7a1ca5..63456c36daa68 100644 --- a/src/plugins/share/server/url_service/short_urls/short_url_client_factory.ts +++ b/src/plugins/share/server/url_service/short_urls/short_url_client_factory.ts @@ -8,7 +8,7 @@ import { SavedObjectsClientContract } from 'kibana/server'; import { ShortUrlStorage } from './types'; -import type { IShortUrlClientFactory } from '../../../common/url_service'; +import type { IShortUrlClientFactory, ILocatorClient } from '../../../common/url_service'; import { ServerShortUrlClient } from './short_url_client'; import { SavedObjectShortUrlStorage } from './storage/saved_object_short_url_storage'; @@ -20,6 +20,11 @@ export interface ServerShortUrlClientFactoryDependencies { * Current version of Kibana, e.g. 7.15.0. */ currentVersion: string; + + /** + * Locators service. + */ + locators: ILocatorClient; } export interface ServerShortUrlClientFactoryCreateParams { @@ -39,9 +44,11 @@ export class ServerShortUrlClientFactory savedObjects: params.savedObjects!, savedObjectType: 'url', }); + const { currentVersion, locators } = this.dependencies; const client = new ServerShortUrlClient({ storage, - currentVersion: this.dependencies.currentVersion, + currentVersion, + locators, }); return client; diff --git a/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.test.ts b/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.test.ts index d178e0b81786c..5d1b0bfa0bf55 100644 --- a/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.test.ts +++ b/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.test.ts @@ -41,6 +41,46 @@ describe('.create()', () => { }); }); +describe('.update()', () => { + test('can update an existing short URL', async () => { + const storage = new MemoryShortUrlStorage(); + const now = Date.now(); + const url1 = await storage.create({ + accessCount: 0, + createDate: now, + accessDate: now, + locator: { + id: 'TEST_LOCATOR', + version: '7.11', + state: { + foo: 'bar', + }, + }, + slug: 'test-slug', + }); + + await storage.update(url1.id, { + accessCount: 1, + }); + + const url2 = await storage.getById(url1.id); + + expect(url1.accessCount).toBe(0); + expect(url2.data.accessCount).toBe(1); + }); + + test('throws when URL does not exist', async () => { + const storage = new MemoryShortUrlStorage(); + const [, error] = await of( + storage.update('DOES_NOT_EXIST', { + accessCount: 1, + }) + ); + + expect(error).toBeInstanceOf(Error); + }); +}); + describe('.getById()', () => { test('can fetch by ID a newly created short URL', async () => { const storage = new MemoryShortUrlStorage(); @@ -58,7 +98,7 @@ describe('.getById()', () => { }, slug: 'test-slug', }); - const url2 = await storage.getById(url1.id); + const url2 = (await storage.getById(url1.id)).data; expect(url2.accessCount).toBe(0); expect(url1.createDate).toBe(now); @@ -112,7 +152,7 @@ describe('.getBySlug()', () => { }, slug: 'test-slug', }); - const url2 = await storage.getBySlug('test-slug'); + const url2 = (await storage.getBySlug('test-slug')).data; expect(url2.accessCount).toBe(0); expect(url1.createDate).toBe(now); diff --git a/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.ts b/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.ts index 40d76a91154ba..fafd00344eecd 100644 --- a/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.ts +++ b/src/plugins/share/server/url_service/short_urls/storage/memory_short_url_storage.ts @@ -9,35 +9,54 @@ import { v4 as uuidv4 } from 'uuid'; import type { SerializableRecord } from '@kbn/utility-types'; import { ShortUrlData } from 'src/plugins/share/common/url_service/short_urls/types'; -import { ShortUrlStorage } from '../types'; +import { SavedObjectReference } from 'kibana/server'; +import { ShortUrlStorage, ShortUrlRecord } from '../types'; + +const clone = <P>(obj: P): P => JSON.parse(JSON.stringify(obj)) as P; export class MemoryShortUrlStorage implements ShortUrlStorage { - private urls = new Map<string, ShortUrlData>(); + private urls = new Map<string, ShortUrlRecord>(); public async create<P extends SerializableRecord = SerializableRecord>( - data: Omit<ShortUrlData<P>, 'id'> + data: Omit<ShortUrlData<P>, 'id'>, + { references = [] }: { references?: SavedObjectReference[] } = {} ): Promise<ShortUrlData<P>> { const id = uuidv4(); - const url: ShortUrlData<P> = { ...data, id }; + const url: ShortUrlRecord<P> = { + data: { ...data, id }, + references, + }; this.urls.set(id, url); - return url; + + return clone(url.data); + } + + public async update<P extends SerializableRecord = SerializableRecord>( + id: string, + data: Partial<Omit<ShortUrlData<P>, 'id'>>, + { references }: { references?: SavedObjectReference[] } = {} + ): Promise<void> { + const so = await this.getById(id); + Object.assign(so.data, data); + if (references) so.references = references; + this.urls.set(id, so); } public async getById<P extends SerializableRecord = SerializableRecord>( id: string - ): Promise<ShortUrlData<P>> { + ): Promise<ShortUrlRecord<P>> { if (!this.urls.has(id)) { throw new Error(`No short url with id "${id}"`); } - return this.urls.get(id)! as ShortUrlData<P>; + return clone(this.urls.get(id)! as ShortUrlRecord<P>); } public async getBySlug<P extends SerializableRecord = SerializableRecord>( slug: string - ): Promise<ShortUrlData<P>> { + ): Promise<ShortUrlRecord<P>> { for (const url of this.urls.values()) { - if (url.slug === slug) { - return url as ShortUrlData<P>; + if (url.data.slug === slug) { + return clone(url as ShortUrlRecord<P>); } } throw new Error(`No short url with slug "${slug}".`); @@ -45,7 +64,7 @@ export class MemoryShortUrlStorage implements ShortUrlStorage { public async exists(slug: string): Promise<boolean> { for (const url of this.urls.values()) { - if (url.slug === slug) { + if (url.data.slug === slug) { return true; } } diff --git a/src/plugins/share/server/url_service/short_urls/storage/saved_object_short_url_storage.ts b/src/plugins/share/server/url_service/short_urls/storage/saved_object_short_url_storage.ts index c66db6d82cdbd..792dfabde3cab 100644 --- a/src/plugins/share/server/url_service/short_urls/storage/saved_object_short_url_storage.ts +++ b/src/plugins/share/server/url_service/short_urls/storage/saved_object_short_url_storage.ts @@ -7,7 +7,8 @@ */ import type { SerializableRecord } from '@kbn/utility-types'; -import { SavedObject, SavedObjectsClientContract } from 'kibana/server'; +import { SavedObject, SavedObjectReference, SavedObjectsClientContract } from 'kibana/server'; +import { ShortUrlRecord } from '..'; import { LEGACY_SHORT_URL_LOCATOR_ID } from '../../../../common/url_service/locators/legacy_short_url_locator'; import { ShortUrlData } from '../../../../common/url_service/short_urls/types'; import { ShortUrlStorage } from '../types'; @@ -85,12 +86,15 @@ const createShortUrlData = <P extends SerializableRecord = SerializableRecord>( }; const createAttributes = <P extends SerializableRecord = SerializableRecord>( - data: Omit<ShortUrlData<P>, 'id'> + data: Partial<Omit<ShortUrlData<P>, 'id'>> ): ShortUrlSavedObjectAttributes => { - const { locator, ...rest } = data; + const { accessCount = 0, accessDate = 0, createDate = 0, slug = '', locator } = data; const attributes: ShortUrlSavedObjectAttributes = { - ...rest, - locatorJSON: JSON.stringify(locator), + accessCount, + accessDate, + createDate, + slug, + locatorJSON: locator ? JSON.stringify(locator) : '', url: '', }; @@ -106,30 +110,49 @@ export class SavedObjectShortUrlStorage implements ShortUrlStorage { constructor(private readonly dependencies: SavedObjectShortUrlStorageDependencies) {} public async create<P extends SerializableRecord = SerializableRecord>( - data: Omit<ShortUrlData<P>, 'id'> + data: Omit<ShortUrlData<P>, 'id'>, + { references }: { references?: SavedObjectReference[] } = {} ): Promise<ShortUrlData<P>> { const { savedObjects, savedObjectType } = this.dependencies; const attributes = createAttributes(data); const savedObject = await savedObjects.create(savedObjectType, attributes, { refresh: true, + references, }); return createShortUrlData<P>(savedObject); } + public async update<P extends SerializableRecord = SerializableRecord>( + id: string, + data: Partial<Omit<ShortUrlData<P>, 'id'>>, + { references }: { references?: SavedObjectReference[] } = {} + ): Promise<void> { + const { savedObjects, savedObjectType } = this.dependencies; + const attributes = createAttributes(data); + + await savedObjects.update(savedObjectType, id, attributes, { + refresh: true, + references, + }); + } + public async getById<P extends SerializableRecord = SerializableRecord>( id: string - ): Promise<ShortUrlData<P>> { + ): Promise<ShortUrlRecord<P>> { const { savedObjects, savedObjectType } = this.dependencies; const savedObject = await savedObjects.get<ShortUrlSavedObjectAttributes>(savedObjectType, id); - return createShortUrlData<P>(savedObject); + return { + data: createShortUrlData<P>(savedObject), + references: savedObject.references, + }; } public async getBySlug<P extends SerializableRecord = SerializableRecord>( slug: string - ): Promise<ShortUrlData<P>> { + ): Promise<ShortUrlRecord<P>> { const { savedObjects } = this.dependencies; const search = `(attributes.slug:"${escapeSearchReservedChars(slug)}")`; const result = await savedObjects.find({ @@ -143,7 +166,10 @@ export class SavedObjectShortUrlStorage implements ShortUrlStorage { const savedObject = result.saved_objects[0] as ShortUrlSavedObject; - return createShortUrlData<P>(savedObject); + return { + data: createShortUrlData<P>(savedObject), + references: savedObject.references, + }; } public async exists(slug: string): Promise<boolean> { diff --git a/src/plugins/share/server/url_service/short_urls/types.ts b/src/plugins/share/server/url_service/short_urls/types.ts index 7aab70ca49519..9a9d9006eb371 100644 --- a/src/plugins/share/server/url_service/short_urls/types.ts +++ b/src/plugins/share/server/url_service/short_urls/types.ts @@ -7,6 +7,7 @@ */ import type { SerializableRecord } from '@kbn/utility-types'; +import { SavedObjectReference } from 'kibana/server'; import { ShortUrlData } from '../../../common/url_service/short_urls/types'; /** @@ -17,20 +18,32 @@ export interface ShortUrlStorage { * Create and store a new short URL entry. */ create<P extends SerializableRecord = SerializableRecord>( - data: Omit<ShortUrlData<P>, 'id'> + data: Omit<ShortUrlData<P>, 'id'>, + options?: { references?: SavedObjectReference[] } ): Promise<ShortUrlData<P>>; + /** + * Update an existing short URL entry. + */ + update<P extends SerializableRecord = SerializableRecord>( + id: string, + data: Partial<Omit<ShortUrlData<P>, 'id'>>, + options?: { references?: SavedObjectReference[] } + ): Promise<void>; + /** * Fetch a short URL entry by ID. */ - getById<P extends SerializableRecord = SerializableRecord>(id: string): Promise<ShortUrlData<P>>; + getById<P extends SerializableRecord = SerializableRecord>( + id: string + ): Promise<ShortUrlRecord<P>>; /** * Fetch a short URL entry by slug. */ getBySlug<P extends SerializableRecord = SerializableRecord>( slug: string - ): Promise<ShortUrlData<P>>; + ): Promise<ShortUrlRecord<P>>; /** * Checks if a short URL exists by slug. @@ -42,3 +55,8 @@ export interface ShortUrlStorage { */ delete(id: string): Promise<void>; } + +export interface ShortUrlRecord<LocatorParams extends SerializableRecord = SerializableRecord> { + data: ShortUrlData<LocatorParams>; + references: SavedObjectReference[]; +} diff --git a/src/plugins/vis_default_editor/kibana.json b/src/plugins/vis_default_editor/kibana.json index e85c5713eb82c..efed1eab1e494 100644 --- a/src/plugins/vis_default_editor/kibana.json +++ b/src/plugins/vis_default_editor/kibana.json @@ -3,7 +3,7 @@ "version": "kibana", "ui": true, "optionalPlugins": ["visualize"], - "requiredBundles": ["kibanaUtils", "kibanaReact", "data", "fieldFormats"], + "requiredBundles": ["kibanaUtils", "kibanaReact", "data", "fieldFormats", "discover"], "owner": { "name": "Vis Editors", "githubTeam": "kibana-vis-editors" diff --git a/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx index dab982e5a8070..f1eebbbdf2116 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx @@ -26,7 +26,7 @@ import { } from 'src/plugins/visualizations/public'; import type { Schema } from 'src/plugins/visualizations/public'; import { TimeRange } from 'src/plugins/data/public'; -import { SavedObject } from 'src/plugins/saved_objects/public'; +import { SavedSearch } from 'src/plugins/discover/public'; import { DefaultEditorNavBar } from './navbar'; import { DefaultEditorControls } from './controls'; import { setStateParamValue, useEditorReducer, useEditorFormState, discardChanges } from './state'; @@ -42,7 +42,7 @@ interface DefaultEditorSideBarProps { vis: Vis; isLinkedSearch: boolean; eventEmitter: EventEmitter; - savedSearch?: SavedObject; + savedSearch?: SavedSearch; timeRange: TimeRange; } diff --git a/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx b/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx index cab27d53b827d..2740f4ff50b4e 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx @@ -25,18 +25,18 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { Vis } from 'src/plugins/visualizations/public'; -import { SavedObject } from 'src/plugins/saved_objects/public'; +import { SavedSearch, getSavedSearchUrl } from '../../../../discover/public'; import { ApplicationStart } from '../../../../../core/public'; import { useKibana } from '../../../../kibana_react/public'; interface LinkedSearchProps { - savedSearch: SavedObject; + savedSearch: SavedSearch; eventEmitter: EventEmitter; } interface SidebarTitleProps { isLinkedSearch: boolean; - savedSearch?: SavedObject; + savedSearch?: SavedSearch; vis: Vis; eventEmitter: EventEmitter; } @@ -55,7 +55,7 @@ export function LinkedSearch({ savedSearch, eventEmitter }: LinkedSearchProps) { }, [eventEmitter]); const onClickViewInDiscover = useCallback(() => { application.navigateToApp('discover', { - path: `#/view/${savedSearch.id}`, + path: getSavedSearchUrl(savedSearch.id), }); }, [application, savedSearch.id]); diff --git a/src/plugins/vis_types/vega/public/data_model/vega_parser.test.js b/src/plugins/vis_types/vega/public/data_model/vega_parser.test.js index cfeed174307ac..13c17b8f4c38f 100644 --- a/src/plugins/vis_types/vega/public/data_model/vega_parser.test.js +++ b/src/plugins/vis_types/vega/public/data_model/vega_parser.test.js @@ -81,6 +81,20 @@ describe(`VegaParser.parseAsync`, () => { }) ) ); + + test(`should return a specific error in case of $schema URL not valid`, async () => { + const vp = new VegaParser({ + $schema: 'https://vega.github.io/schema/vega-lite/v4.jsonanythingtobreakthis', + mark: 'circle', + encoding: { row: { field: 'a' } }, + }); + + await vp.parseAsync(); + + expect(vp.error).toBe( + 'The URL for the JSON "$schema" is incorrect. Correct the URL, then click Update.' + ); + }); }); describe(`VegaParser._setDefaultValue`, () => { diff --git a/src/plugins/vis_types/vega/public/data_model/vega_parser.ts b/src/plugins/vis_types/vega/public/data_model/vega_parser.ts index 9000fed7f6116..bf2a6be25c71a 100644 --- a/src/plugins/vis_types/vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_types/vega/public/data_model/vega_parser.ts @@ -553,25 +553,37 @@ The URL is an identifier only. Kibana and your browser will never access this UR * @private */ private parseSchema(spec: VegaSpec) { - const schema = schemaParser(spec.$schema); - const isVegaLite = schema.library === 'vega-lite'; - const libVersion = isVegaLite ? vegaLiteVersion : vegaVersion; + try { + const schema = schemaParser(spec.$schema); + const isVegaLite = schema.library === 'vega-lite'; + const libVersion = isVegaLite ? vegaLiteVersion : vegaVersion; - if (versionCompare(schema.version, libVersion) > 0) { - this._onWarning( - i18n.translate('visTypeVega.vegaParser.notValidLibraryVersionForInputSpecWarningMessage', { + if (versionCompare(schema.version, libVersion) > 0) { + this._onWarning( + i18n.translate( + 'visTypeVega.vegaParser.notValidLibraryVersionForInputSpecWarningMessage', + { + defaultMessage: + 'The input spec uses {schemaLibrary} {schemaVersion}, but current version of {schemaLibrary} is {libraryVersion}.', + values: { + schemaLibrary: schema.library, + schemaVersion: schema.version, + libraryVersion: libVersion, + }, + } + ) + ); + } + + return { isVegaLite, libVersion }; + } catch (e) { + throw Error( + i18n.translate('visTypeVega.vegaParser.notValidSchemaForInputSpec', { defaultMessage: - 'The input spec uses {schemaLibrary} {schemaVersion}, but current version of {schemaLibrary} is {libraryVersion}.', - values: { - schemaLibrary: schema.library, - schemaVersion: schema.version, - libraryVersion: libVersion, - }, + 'The URL for the JSON "$schema" is incorrect. Correct the URL, then click Update.', }) ); } - - return { isVegaLite, libVersion }; } /** diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index 47f544ce2f5d3..87095f5c389ed 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -23,9 +23,9 @@ import { setAggs, setChrome, setOverlays, - setSavedSearchLoader, setEmbeddable, setDocLinks, + setSpaces, } from './services'; import { VISUALIZE_EMBEDDABLE_TYPE, @@ -51,8 +51,6 @@ import { findListItems, } from './utils/saved_visualize_utils'; -import { createSavedSearchesLoader } from '../../discover/public'; - import type { PluginInitializerContext, CoreSetup, @@ -191,6 +189,11 @@ export class VisualizationsPlugin setAggs(data.search.aggs); setOverlays(core.overlays); setChrome(core.chrome); + + if (spaces) { + setSpaces(spaces); + } + const savedVisualizationsLoader = createSavedVisLoader({ savedObjectsClient: core.savedObjects.client, indexPatterns: data.indexPatterns, @@ -198,11 +201,7 @@ export class VisualizationsPlugin visualizationTypes: types, }); setSavedVisualizationsLoader(savedVisualizationsLoader); - const savedSearchLoader = createSavedSearchesLoader({ - savedObjectsClient: core.savedObjects.client, - savedObjects, - }); - setSavedSearchLoader(savedSearchLoader); + return { ...types, showNewVisModal, diff --git a/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts b/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts index fbd8e414c2738..aa8183eb8da39 100644 --- a/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts +++ b/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts @@ -16,8 +16,8 @@ import type { SavedObjectsStart, SavedObject } from '../../../../plugins/saved_objects/public'; // @ts-ignore import { updateOldState } from '../legacy/vis_update_state'; +import { __LEGACY } from '../../../discover/public'; import { extractReferences, injectReferences } from '../utils/saved_visualization_references'; -import { createSavedSearchesLoader } from '../../../discover/public'; import type { SavedObjectsClientContract } from '../../../../core/public'; import type { IndexPatternsContract } from '../../../../plugins/data/public'; import type { ISavedVis } from '../types'; @@ -30,7 +30,7 @@ export interface SavedVisServices { /** @deprecated **/ export function createSavedVisClass(services: SavedVisServices) { - const savedSearch = createSavedSearchesLoader(services); + const savedSearch = __LEGACY.createSavedSearchesLoader(services); class SavedVis extends services.savedObjects.SavedObjectClass { public static type: string = 'visualization'; diff --git a/src/plugins/visualizations/public/services.ts b/src/plugins/visualizations/public/services.ts index f1ab9077cd207..ed18884d9dc83 100644 --- a/src/plugins/visualizations/public/services.ts +++ b/src/plugins/visualizations/public/services.ts @@ -18,13 +18,14 @@ import type { } from '../../../core/public'; import type { TypesStart } from './vis_types'; import { createGetterSetter } from '../../../plugins/kibana_utils/public'; -import { DataPublicPluginStart, TimefilterContract } from '../../../plugins/data/public'; -import { UsageCollectionSetup } from '../../../plugins/usage_collection/public'; -import { ExpressionsStart } from '../../../plugins/expressions/public'; -import { UiActionsStart } from '../../../plugins/ui_actions/public'; -import { SavedVisualizationsLoader } from './saved_visualizations'; -import { SavedObjectLoader } from '../../saved_objects/public'; -import { EmbeddableStart } from '../../embeddable/public'; +import type { DataPublicPluginStart, TimefilterContract } from '../../../plugins/data/public'; +import type { UsageCollectionSetup } from '../../../plugins/usage_collection/public'; +import type { ExpressionsStart } from '../../../plugins/expressions/public'; +import type { UiActionsStart } from '../../../plugins/ui_actions/public'; +import type { SavedVisualizationsLoader } from './saved_visualizations'; +import type { EmbeddableStart } from '../../embeddable/public'; + +import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; export const [getUISettings, setUISettings] = createGetterSetter<IUiSettingsClient>('UISettings'); @@ -47,8 +48,10 @@ export const [getTimeFilter, setTimeFilter] = createGetterSetter<TimefilterContr export const [getSearch, setSearch] = createGetterSetter<DataPublicPluginStart['search']>('Search'); -export const [getUsageCollector, setUsageCollector] = - createGetterSetter<UsageCollectionSetup>('UsageCollection'); +export const [getUsageCollector, setUsageCollector] = createGetterSetter<UsageCollectionSetup>( + 'UsageCollection', + false +); export const [getExpressions, setExpressions] = createGetterSetter<ExpressionsStart>('Expressions'); @@ -64,5 +67,4 @@ export const [getOverlays, setOverlays] = createGetterSetter<OverlayStart>('Over export const [getChrome, setChrome] = createGetterSetter<ChromeStart>('Chrome'); -export const [getSavedSearchLoader, setSavedSearchLoader] = - createGetterSetter<SavedObjectLoader>('savedSearchLoader'); +export const [getSpaces, setSpaces] = createGetterSetter<SpacesPluginStart>('Spaces', false); diff --git a/src/plugins/visualizations/public/vis.ts b/src/plugins/visualizations/public/vis.ts index dfab4ecfc3cd8..2a1e7f2c8c673 100644 --- a/src/plugins/visualizations/public/vis.ts +++ b/src/plugins/visualizations/public/vis.ts @@ -21,17 +21,19 @@ import { Assign } from '@kbn/utility-types'; import { i18n } from '@kbn/i18n'; import { PersistedState } from './persisted_state'; -import { getTypes, getAggs, getSearch, getSavedSearchLoader } from './services'; +import { getTypes, getAggs, getSearch, getSavedObjects, getSpaces } from './services'; import { IAggConfigs, IndexPattern, ISearchSource, AggConfigSerialized, SearchSourceFields, -} from '../../../plugins/data/public'; +} from '../../data/public'; import { BaseVisType } from './vis_types'; import { VisParams } from '../common/types'; +import { getSavedSearch, throwErrorOnSavedSearchUrlConflict } from '../../discover/public'; + export interface SerializedVisData { expression?: string; aggs: AggConfigSerialized[]; @@ -58,14 +60,20 @@ export interface VisData { } const getSearchSource = async (inputSearchSource: ISearchSource, savedSearchId?: string) => { - const searchSource = inputSearchSource.createCopy(); if (savedSearchId) { - const savedSearch = await getSavedSearchLoader().get(savedSearchId); + const savedSearch = await getSavedSearch(savedSearchId, { + search: getSearch(), + savedObjectsClient: getSavedObjects().client, + spaces: getSpaces(), + }); + + await throwErrorOnSavedSearchUrlConflict(savedSearch); - searchSource.setParent(savedSearch.searchSource); + if (savedSearch?.searchSource) { + inputSearchSource.setParent(savedSearch.searchSource); + } } - searchSource.setField('size', 0); - return searchSource; + return inputSearchSource; }; type PartialVisState = Assign<SerializedVis, { data: Partial<SerializedVisData> }>; diff --git a/src/plugins/visualize/public/application/types.ts b/src/plugins/visualize/public/application/types.ts index 4debd9a4a7b7d..e77520c962d88 100644 --- a/src/plugins/visualize/public/application/types.ts +++ b/src/plugins/visualize/public/application/types.ts @@ -8,7 +8,6 @@ import type { EventEmitter } from 'events'; import type { History } from 'history'; - import type { SerializableRecord } from '@kbn/utility-types'; import type { @@ -38,7 +37,7 @@ import type { import type { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public'; import type { Query, Filter, DataPublicPluginStart, TimeRange } from 'src/plugins/data/public'; import type { SharePluginStart } from 'src/plugins/share/public'; -import type { SavedObjectsStart, SavedObject } from 'src/plugins/saved_objects/public'; +import type { SavedObjectsStart } from 'src/plugins/saved_objects/public'; import type { EmbeddableStart, EmbeddableStateTransfer } from 'src/plugins/embeddable/public'; import type { UrlForwardingStart } from 'src/plugins/url_forwarding/public'; import type { PresentationUtilPluginStart } from 'src/plugins/presentation_util/public'; @@ -46,6 +45,7 @@ import type { SpacesPluginStart } from '../../../../../x-pack/plugins/spaces/pub import type { DashboardStart } from '../../../dashboard/public'; import type { SavedObjectsTaggingApi } from '../../../saved_objects_tagging_oss/public'; import type { UsageCollectionStart } from '../../../usage_collection/public'; +import type { SavedSearch } from '../../../discover/public'; import { PureVisState } from '../../common/types'; @@ -108,20 +108,15 @@ export interface VisualizeServices extends CoreStart { spaces?: SpacesPluginStart; } -export interface SavedVisInstance { - vis: Vis; - savedVis: VisSavedObject; - savedSearch?: SavedObject; - embeddableHandler: VisualizeEmbeddableContract; -} - -export interface ByValueVisInstance { +export interface VisInstance { vis: Vis; savedVis: VisSavedObject; - savedSearch?: SavedObject; + savedSearch?: SavedSearch; embeddableHandler: VisualizeEmbeddableContract; } +export type SavedVisInstance = VisInstance; +export type ByValueVisInstance = VisInstance; export type VisualizeEditorVisInstance = SavedVisInstance | ByValueVisInstance; export type VisEditorConstructor<TVisParams = VisParams> = new ( @@ -142,7 +137,7 @@ export interface EditorRenderProps { filters: Filter[]; timeRange: TimeRange; query?: Query; - savedSearch?: SavedObject; + savedSearch?: SavedSearch; uiState: PersistedState; /** * Flag to determine if visualiztion is linked to the saved search diff --git a/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts b/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts index 209516793d69d..777ba244c06a1 100644 --- a/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts +++ b/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { createSavedSearchesLoader } from '../../../../discover/public'; +import { getSavedSearch } from '../../../../discover/public'; import type { VisualizeInput, VisSavedObject, @@ -21,13 +21,13 @@ import { createVisualizeServicesMock } from './mocks'; import { VisualizeServices } from '../types'; import { BehaviorSubject } from 'rxjs'; -const mockSavedSearchObj = {}; -const mockGetSavedSearch = jest.fn(() => mockSavedSearchObj); - jest.mock('../../../../discover/public', () => ({ - createSavedSearchesLoader: jest.fn(() => ({ - get: mockGetSavedSearch, - })), + getSavedSearch: jest.fn().mockResolvedValue({ + id: 'savedSearch', + title: 'savedSearchTitle', + searchSource: {}, + }), + throwErrorOnSavedSearchUrlConflict: jest.fn(), })); let savedVisMock: VisSavedObject; @@ -116,9 +116,14 @@ describe('getVisualizationInstance', () => { visMock.data.savedSearchId = 'saved_search_id'; const { savedSearch } = await getVisualizationInstance(mockServices, 'saved_vis_id'); - expect(createSavedSearchesLoader).toHaveBeenCalled(); - expect(mockGetSavedSearch).toHaveBeenCalledWith(visMock.data.savedSearchId); - expect(savedSearch).toBe(mockSavedSearchObj); + expect(getSavedSearch).toHaveBeenCalled(); + expect(savedSearch).toMatchInlineSnapshot(` + Object { + "id": "savedSearch", + "searchSource": Object {}, + "title": "savedSearchTitle", + } + `); }); test('should subscribe on embeddable handler updates and send toasts on errors', async () => { diff --git a/src/plugins/visualize/public/application/utils/get_visualization_instance.ts b/src/plugins/visualize/public/application/utils/get_visualization_instance.ts index faf25ff28cec0..876501d5f099b 100644 --- a/src/plugins/visualize/public/application/utils/get_visualization_instance.ts +++ b/src/plugins/visualize/public/application/utils/get_visualization_instance.ts @@ -14,10 +14,13 @@ import { VisualizeInput, } from 'src/plugins/visualizations/public'; import { SearchSourceFields } from 'src/plugins/data/public'; -import { SavedObject } from 'src/plugins/saved_objects/public'; import { cloneDeep } from 'lodash'; import { ExpressionValueError } from 'src/plugins/expressions/public'; -import { createSavedSearchesLoader } from '../../../../discover/public'; +import { + getSavedSearch, + SavedSearch, + throwErrorOnSavedSearchUrlConflict, +} from '../../../../discover/public'; import { SavedFieldNotFound, SavedFieldTypeInvalidForAgg } from '../../../../kibana_utils/common'; import { VisualizeServices } from '../types'; @@ -33,8 +36,7 @@ const createVisualizeEmbeddableAndLinkSavedSearch = async ( vis: Vis, visualizeServices: VisualizeServices ) => { - const { data, createVisEmbeddableFromObject, savedObjects, savedObjectsPublic } = - visualizeServices; + const { data, createVisEmbeddableFromObject, savedObjects, spaces } = visualizeServices; const embeddableHandler = (await createVisEmbeddableFromObject(vis, { id: '', timeRange: data.query.timefilter.timefilter.getTime(), @@ -50,13 +52,16 @@ const createVisualizeEmbeddableAndLinkSavedSearch = async ( } }); - let savedSearch: SavedObject | undefined; + let savedSearch: SavedSearch | undefined; if (vis.data.savedSearchId) { - savedSearch = await createSavedSearchesLoader({ + savedSearch = await getSavedSearch(vis.data.savedSearchId, { + search: data.search, savedObjectsClient: savedObjects.client, - savedObjects: savedObjectsPublic, - }).get(vis.data.savedSearchId); + spaces, + }); + + await throwErrorOnSavedSearchUrlConflict(savedSearch); } return { savedSearch, embeddableHandler }; diff --git a/src/plugins/visualize/public/plugin.ts b/src/plugins/visualize/public/plugin.ts index c9df6a6ec57d8..7ff3434286b6b 100644 --- a/src/plugins/visualize/public/plugin.ts +++ b/src/plugins/visualize/public/plugin.ts @@ -28,7 +28,6 @@ import { createKbnUrlStateStorage, withNotifyOnErrors, } from '../../kibana_utils/public'; -import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; import { VisualizeConstants } from './application/visualize_constants'; import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../data/public'; @@ -45,6 +44,7 @@ import type { EmbeddableStart } from '../../embeddable/public'; import type { DashboardStart } from '../../dashboard/public'; import type { SavedObjectTaggingOssPluginStart } from '../../saved_objects_tagging_oss/public'; import type { UsageCollectionStart } from '../../usage_collection/public'; +import type { SpacesApi } from '../../../../x-pack/plugins/spaces/public'; import { setVisEditorsRegistry, setUISettings, setUsageCollector } from './services'; import { createVisEditorsRegistry, VisEditorsRegistry } from './vis_editors_registry'; @@ -62,7 +62,7 @@ export interface VisualizePluginStartDependencies { savedObjectsTaggingOss?: SavedObjectTaggingOssPluginStart; presentationUtil: PresentationUtilPluginStart; usageCollection?: UsageCollectionStart; - spaces: SpacesPluginStart; + spaces?: SpacesApi; } export interface VisualizePluginSetupDependencies { diff --git a/src/plugins/visualize/public/services.ts b/src/plugins/visualize/public/services.ts index 7efb054fc636a..3f91762c60780 100644 --- a/src/plugins/visualize/public/services.ts +++ b/src/plugins/visualize/public/services.ts @@ -13,8 +13,10 @@ import type { UsageCollectionStart } from '../../usage_collection/public'; export const [getUISettings, setUISettings] = createGetterSetter<IUiSettingsClient>('UISettings'); -export const [getUsageCollector, setUsageCollector] = - createGetterSetter<UsageCollectionStart>('UsageCollection'); +export const [getUsageCollector, setUsageCollector] = createGetterSetter<UsageCollectionStart>( + 'UsageCollection', + false +); export const [getVisEditorsRegistry, setVisEditorsRegistry] = createGetterSetter<VisEditorsRegistry>('VisEditorsRegistry'); diff --git a/test/examples/embeddables/dashboard.ts b/test/examples/embeddables/dashboard.ts index 77ad5a5da9eeb..b97905ca9ce6a 100644 --- a/test/examples/embeddables/dashboard.ts +++ b/test/examples/embeddables/dashboard.ts @@ -95,10 +95,10 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const esArchiver = getService('esArchiver'); const testSubjects = getService('testSubjects'); const pieChart = getService('pieChart'); - const browser = getService('browser'); const dashboardExpect = getService('dashboardExpect'); const elasticChart = getService('elasticChart'); const PageObjects = getPageObjects(['common', 'visChart']); + const monacoEditor = getService('monacoEditor'); describe('dashboard container', () => { before(async () => { @@ -128,17 +128,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide }); async function updateInput(input: string) { - const editorWrapper = await ( - await testSubjects.find('dashboardEmbeddableByValueInputEditor') - ).findByClassName('ace_editor'); - const editorId = await editorWrapper.getAttribute('id'); - await browser.execute( - (_editorId: string, _input: string) => { - return (window as any).ace.edit(_editorId).setValue(_input); - }, - editorId, - input - ); + await monacoEditor.setCodeEditorValue(input); await testSubjects.click('dashboardEmbeddableByValueInputSubmit'); } } diff --git a/test/functional/apps/discover/_discover_fields_api.ts b/test/functional/apps/discover/_discover_fields_api.ts index 42e2a94b36462..700c865031cd6 100644 --- a/test/functional/apps/discover/_discover_fields_api.ts +++ b/test/functional/apps/discover/_discover_fields_api.ts @@ -15,7 +15,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker']); + const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker', 'settings']); const defaultSettings = { defaultIndex: 'logstash-*', 'discover:searchFieldsFromSource': false, @@ -67,5 +67,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.clickDocViewerTab(1); await PageObjects.discover.expectSourceViewerToExist(); }); + + it('switches to _source column when fields API is no longer used', async function () { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaSettings(); + await PageObjects.settings.toggleAdvancedSettingCheckbox('discover:searchFieldsFromSource'); + + await PageObjects.common.navigateToApp('discover'); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + + expect(await PageObjects.discover.getDocHeader()).to.have.string('_source'); + }); + + it('switches to Document column when fields API is used', async function () { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaSettings(); + await PageObjects.settings.toggleAdvancedSettingCheckbox('discover:searchFieldsFromSource'); + + await PageObjects.common.navigateToApp('discover'); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + + expect(await PageObjects.discover.getDocHeader()).to.have.string('Document'); + }); }); } diff --git a/test/functional/apps/saved_objects_management/inspect_saved_objects.ts b/test/functional/apps/saved_objects_management/inspect_saved_objects.ts index 839c262acffa0..7fff2cc001844 100644 --- a/test/functional/apps/saved_objects_management/inspect_saved_objects.ts +++ b/test/functional/apps/saved_objects_management/inspect_saved_objects.ts @@ -32,7 +32,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { return bools.every((currBool) => currBool === true); }; - describe('saved objects edition page', () => { + // FLAKY: https://github.com/elastic/kibana/issues/68400 + describe.skip('saved objects edition page', () => { beforeEach(async () => { await esArchiver.load( 'test/functional/fixtures/es_archiver/saved_objects_management/edit_saved_object' diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts index 2645148467d58..b929a78072868 100644 --- a/test/functional/page_objects/settings_page.ts +++ b/test/functional/page_objects/settings_page.ts @@ -21,6 +21,7 @@ export class SettingsPageObject extends FtrService { private readonly header = this.ctx.getPageObject('header'); private readonly common = this.ctx.getPageObject('common'); private readonly savedObjects = this.ctx.getPageObject('savedObjects'); + private readonly monacoEditor = this.ctx.getService('monacoEditor'); async clickNavigation() { await this.find.clickDisplayedByCssSelector('.app-link:nth-child(5) a'); @@ -725,14 +726,7 @@ export class SettingsPageObject extends FtrService { async setScriptedFieldScript(script: string) { this.log.debug('set scripted field script = ' + script); - const aceEditorCssSelector = '[data-test-subj="editorFieldScript"] .ace_editor'; - const editor = await this.find.byCssSelector(aceEditorCssSelector); - await editor.click(); - const existingText = await editor.getVisibleText(); - for (let i = 0; i < existingText.length; i++) { - await this.browser.pressKeys(this.browser.keys.BACK_SPACE); - } - await this.browser.pressKeys(...script.split('')); + await this.monacoEditor.setCodeEditorValue(script); } async openScriptedFieldHelp(activeTab: string) { diff --git a/test/functional/services/remote/remote.ts b/test/functional/services/remote/remote.ts index 5bf99b4bf1136..653058959b839 100644 --- a/test/functional/services/remote/remote.ts +++ b/test/functional/services/remote/remote.ts @@ -92,7 +92,7 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { .subscribe({ next({ message, level }) { const msg = message.replace(/\\n/g, '\n'); - log[level === 'SEVERE' || level === 'error' ? 'error' : 'debug']( + log[level === 'SEVERE' || level === 'error' ? 'warning' : 'debug']( `browser[${level}] ${msg}` ); }, diff --git a/vars/kibanaPipeline.groovy b/vars/kibanaPipeline.groovy index 21e41ce55781f..daf6ca7a8e993 100644 --- a/vars/kibanaPipeline.groovy +++ b/vars/kibanaPipeline.groovy @@ -203,7 +203,6 @@ def withGcsArtifactUpload(workerName, closure) { 'x-pack/test/**/screenshots/diff/*.png', 'x-pack/test/**/screenshots/failure/*.png', 'x-pack/test/**/screenshots/session/*.png', - 'x-pack/test/functional/apps/reporting/reports/session/*.pdf', 'x-pack/test/functional/failure_debug/html/*.html', '.es/**/*.hprof' ] diff --git a/x-pack/examples/reporting_example/public/components/app.tsx b/x-pack/examples/reporting_example/public/components/app.tsx index a34cd0ab518de..3e2f08fc89c7b 100644 --- a/x-pack/examples/reporting_example/public/components/app.tsx +++ b/x-pack/examples/reporting_example/public/components/app.tsx @@ -244,7 +244,12 @@ export const ReportingExampleApp = ({ )} </EuiFlexItem> {logos.map((item, index) => ( - <EuiFlexItem key={index} data-shared-item> + <EuiFlexItem + key={index} + data-shared-item + data-shared-render-error + data-render-error="This is an example error" + > <EuiCard icon={<EuiIcon size="xxl" type={`logo${item}`} />} title={`Elastic ${item}`} diff --git a/x-pack/plugins/actions/README.md b/x-pack/plugins/actions/README.md index b19e89a599840..0d66c9d30f8b9 100644 --- a/x-pack/plugins/actions/README.md +++ b/x-pack/plugins/actions/README.md @@ -33,29 +33,36 @@ Table of Contents - [actionsClient.execute(options)](#actionsclientexecuteoptions) - [Example](#example-2) - [Built-in Action Types](#built-in-action-types) - - [ServiceNow](#servicenow) + - [ServiceNow ITSM](#servicenow-itsm) - [`params`](#params) - [`subActionParams (pushToService)`](#subactionparams-pushtoservice) - [`subActionParams (getFields)`](#subactionparams-getfields) - [`subActionParams (getIncident)`](#subactionparams-getincident) - [`subActionParams (getChoices)`](#subactionparams-getchoices) - - [Jira](#jira) + - [ServiceNow Sec Ops](#servicenow-sec-ops) - [`params`](#params-1) - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-1) + - [`subActionParams (getFields)`](#subactionparams-getfields-1) - [`subActionParams (getIncident)`](#subactionparams-getincident-1) + - [`subActionParams (getChoices)`](#subactionparams-getchoices-1) + - [| fields | An array of fields. Example: `[priority, category]`. | string[] |](#-fields----an-array-of-fields-example-priority-category--string-) + - [Jira](#jira) + - [`params`](#params-2) + - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-2) + - [`subActionParams (getIncident)`](#subactionparams-getincident-2) - [`subActionParams (issueTypes)`](#subactionparams-issuetypes) - [`subActionParams (fieldsByIssueType)`](#subactionparams-fieldsbyissuetype) - [`subActionParams (issues)`](#subactionparams-issues) - [`subActionParams (issue)`](#subactionparams-issue) - - [`subActionParams (getFields)`](#subactionparams-getfields-1) - - [IBM Resilient](#ibm-resilient) - - [`params`](#params-2) - - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-2) - [`subActionParams (getFields)`](#subactionparams-getfields-2) + - [IBM Resilient](#ibm-resilient) + - [`params`](#params-3) + - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-3) + - [`subActionParams (getFields)`](#subactionparams-getfields-3) - [`subActionParams (incidentTypes)`](#subactionparams-incidenttypes) - [`subActionParams (severity)`](#subactionparams-severity) - [Swimlane](#swimlane) - - [`params`](#params-3) + - [`params`](#params-4) - [| severity | The severity of the incident. | string _(optional)_ |](#-severity-----the-severity-of-the-incident-----string-optional-) - [Command Line Utility](#command-line-utility) - [Developing New Action Types](#developing-new-action-types) @@ -246,9 +253,9 @@ Kibana ships with a set of built-in action types. See [Actions and connector typ In addition to the documented configurations, several built in action type offer additional `params` configurations. -## ServiceNow +## ServiceNow ITSM -The [ServiceNow user documentation `params`](https://www.elastic.co/guide/en/kibana/master/servicenow-action-type.html) lists configuration properties for the `pushToService` subaction. In addition, several other subaction types are available. +The [ServiceNow ITSM user documentation `params`](https://www.elastic.co/guide/en/kibana/master/servicenow-action-type.html) lists configuration properties for the `pushToService` subaction. In addition, several other subaction types are available. ### `params` | Property | Description | Type | @@ -265,16 +272,18 @@ The [ServiceNow user documentation `params`](https://www.elastic.co/guide/en/kib The following table describes the properties of the `incident` object. -| Property | Description | Type | -| ----------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------- | -| short_description | The title of the incident. | string | -| description | The description of the incident. | string _(optional)_ | -| externalId | The ID of the incident in ServiceNow. If present, the incident is updated. Otherwise, a new incident is created. | string _(optional)_ | -| severity | The severity in ServiceNow. | string _(optional)_ | -| urgency | The urgency in ServiceNow. | string _(optional)_ | -| impact | The impact in ServiceNow. | string _(optional)_ | -| category | The category in ServiceNow. | string _(optional)_ | -| subcategory | The subcategory in ServiceNow. | string _(optional)_ | +| Property | Description | Type | +| ------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------- | +| short_description | The title of the incident. | string | +| description | The description of the incident. | string _(optional)_ | +| externalId | The ID of the incident in ServiceNow. If present, the incident is updated. Otherwise, a new incident is created. | string _(optional)_ | +| severity | The severity in ServiceNow. | string _(optional)_ | +| urgency | The urgency in ServiceNow. | string _(optional)_ | +| impact | The impact in ServiceNow. | string _(optional)_ | +| category | The category in ServiceNow. | string _(optional)_ | +| subcategory | The subcategory in ServiceNow. | string _(optional)_ | +| correlation_id | The correlation id of the incident. | string _(optional)_ | +| correlation_display | The correlation display of the ServiceNow. | string _(optional)_ | #### `subActionParams (getFields)` @@ -289,12 +298,64 @@ No parameters for the `getFields` subaction. Provide an empty object `{}`. #### `subActionParams (getChoices)` -| Property | Description | Type | -| -------- | ------------------------------------------------------------ | -------- | -| fields | An array of fields. Example: `[priority, category, impact]`. | string[] | +| Property | Description | Type | +| -------- | -------------------------------------------------- | -------- | +| fields | An array of fields. Example: `[category, impact]`. | string[] | --- +## ServiceNow Sec Ops + +The [ServiceNow SecOps user documentation `params`](https://www.elastic.co/guide/en/kibana/master/servicenow-sir-action-type.html) lists configuration properties for the `pushToService` subaction. In addition, several other subaction types are available. + +### `params` + +| Property | Description | Type | +| --------------- | -------------------------------------------------------------------------------------------------- | ------ | +| subAction | The subaction to perform. It can be `pushToService`, `getFields`, `getIncident`, and `getChoices`. | string | +| subActionParams | The parameters of the subaction. | object | + +#### `subActionParams (pushToService)` + +| Property | Description | Type | +| -------- | ------------------------------------------------------------------------------------------------------------- | --------------------- | +| incident | The ServiceNow security incident. | object | +| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }`. | object[] _(optional)_ | + +The following table describes the properties of the `incident` object. + +| Property | Description | Type | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| short_description | The title of the security incident. | string | +| description | The description of the security incident. | string _(optional)_ | +| externalId | The ID of the security incident in ServiceNow. If present, the security incident is updated. Otherwise, a new security incident is created. | string _(optional)_ | +| priority | The priority in ServiceNow. | string _(optional)_ | +| dest_ip | A list of destination IPs related to the security incident. The IPs will be added as observables to the security incident. | (string \| string[]) _(optional)_ | +| source_ip | A list of source IPs related to the security incident. The IPs will be added as observables to the security incident. | (string \| string[]) _(optional)_ | +| malware_hash | A list of malware hashes related to the security incident. The hashes will be added as observables to the security incident. | (string \| string[]) _(optional)_ | +| malware_url | A list of malware URLs related to the security incident. The URLs will be added as observables to the security incident. | (string \| string[]) _(optional)_ | +| category | The category in ServiceNow. | string _(optional)_ | +| subcategory | The subcategory in ServiceNow. | string _(optional)_ | +| correlation_id | The correlation id of the security incident. | string _(optional)_ | +| correlation_display | The correlation display of the security incident. | string _(optional)_ | + +#### `subActionParams (getFields)` + +No parameters for the `getFields` subaction. Provide an empty object `{}`. + +#### `subActionParams (getIncident)` + +| Property | Description | Type | +| ---------- | ---------------------------------------------- | ------ | +| externalId | The ID of the security incident in ServiceNow. | string | + + +#### `subActionParams (getChoices)` + +| Property | Description | Type | +| -------- | ---------------------------------------------------- | -------- | +| fields | An array of fields. Example: `[priority, category]`. | string[] | +--- ## Jira The [Jira user documentation `params`](https://www.elastic.co/guide/en/kibana/master/jira-action-type.html) lists configuration properties for the `pushToService` subaction. In addition, several other subaction types are available. diff --git a/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts b/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts index 5d83b658111e4..7710ff79d08b4 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts @@ -143,7 +143,7 @@ export function getActionType({ }), validate: { config: schema.object(configSchemaProps, { - validate: curry(valdiateActionTypeConfig)(configurationUtilities), + validate: curry(validateActionTypeConfig)(configurationUtilities), }), secrets: SecretsSchema, params: ParamsSchema, @@ -152,7 +152,7 @@ export function getActionType({ }; } -function valdiateActionTypeConfig( +function validateActionTypeConfig( configurationUtilities: ActionsConfigurationUtilities, configObject: ActionTypeConfigType ) { diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 8d24e48d4d515..e1f66263729e2 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -25,6 +25,7 @@ describe('api', () => { const res = await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -57,6 +58,7 @@ describe('api', () => { const res = await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -78,6 +80,7 @@ describe('api', () => { await api.pushToService({ externalService, params, + config: {}, secrets: { username: 'elastic', password: 'elastic' }, logger: mockedLogger, commentFieldKey: 'comments', @@ -93,6 +96,9 @@ describe('api', () => { caller_id: 'elastic', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', + opened_by: 'elastic', }, }); expect(externalService.updateIncident).not.toHaveBeenCalled(); @@ -103,6 +109,7 @@ describe('api', () => { await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -118,6 +125,8 @@ describe('api', () => { comments: 'A comment', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-1', }); @@ -132,6 +141,8 @@ describe('api', () => { comments: 'Another comment', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-1', }); @@ -142,6 +153,7 @@ describe('api', () => { await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'work_notes', @@ -157,6 +169,8 @@ describe('api', () => { work_notes: 'A comment', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-1', }); @@ -171,6 +185,8 @@ describe('api', () => { work_notes: 'Another comment', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-1', }); @@ -182,6 +198,7 @@ describe('api', () => { const res = await api.pushToService({ externalService, params: apiParams, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -210,6 +227,7 @@ describe('api', () => { const res = await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -228,6 +246,7 @@ describe('api', () => { await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -243,6 +262,8 @@ describe('api', () => { subcategory: 'os', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, }); expect(externalService.createIncident).not.toHaveBeenCalled(); @@ -253,6 +274,7 @@ describe('api', () => { await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'comments', @@ -267,6 +289,8 @@ describe('api', () => { subcategory: 'os', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-3', }); @@ -281,6 +305,8 @@ describe('api', () => { comments: 'A comment', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-2', }); @@ -291,6 +317,7 @@ describe('api', () => { await api.pushToService({ externalService, params, + config: {}, secrets: {}, logger: mockedLogger, commentFieldKey: 'work_notes', @@ -305,6 +332,8 @@ describe('api', () => { subcategory: 'os', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-3', }); @@ -319,6 +348,8 @@ describe('api', () => { work_notes: 'A comment', description: 'Incident description', short_description: 'Incident title', + correlation_display: 'Alerting', + correlation_id: 'ruleId', }, incidentId: 'incident-2', }); @@ -344,4 +375,23 @@ describe('api', () => { expect(res).toEqual(serviceNowChoices); }); }); + + describe('getIncident', () => { + test('it gets the incident correctly', async () => { + const res = await api.getIncident({ + externalService, + params: { + externalId: 'incident-1', + }, + }); + expect(res).toEqual({ + description: 'description from servicenow', + id: 'incident-1', + pushedDate: '2020-03-10T12:24:20.000Z', + short_description: 'title from servicenow', + title: 'INC01', + url: 'https://instance.service-now.com/nav_to.do?uri=incident.do?sys_id=123', + }); + }); + }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 4120c07c32303..88cdfd069cf1b 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -6,7 +6,7 @@ */ import { - ExternalServiceApi, + ExternalServiceAPI, GetChoicesHandlerArgs, GetChoicesResponse, GetCommonFieldsHandlerArgs, @@ -19,7 +19,11 @@ import { } from './types'; const handshakeHandler = async ({ externalService, params }: HandshakeApiHandlerArgs) => {}; -const getIncidentHandler = async ({ externalService, params }: GetIncidentApiHandlerArgs) => {}; +const getIncidentHandler = async ({ externalService, params }: GetIncidentApiHandlerArgs) => { + const { externalId: id } = params; + const res = await externalService.getIncident(id); + return res; +}; const pushToServiceHandler = async ({ externalService, @@ -42,6 +46,7 @@ const pushToServiceHandler = async ({ incident: { ...incident, caller_id: secrets.username, + opened_by: secrets.username, }, }); } @@ -84,7 +89,7 @@ const getChoicesHandler = async ({ return res; }; -export const api: ExternalServiceApi = { +export const api: ExternalServiceAPI = { getChoices: getChoicesHandler, getFields: getFieldsHandler, getIncident: getIncidentHandler, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts new file mode 100644 index 0000000000000..358af7cd2e9ef --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts @@ -0,0 +1,286 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 } from '../../../../../../src/core/server'; +import { externalServiceSIRMock, sirParams } from './mocks'; +import { ExternalServiceSIR, ObservableTypes } from './types'; +import { apiSIR, combineObservables, formatObservables, prepareParams } from './api_sir'; +let mockedLogger: jest.Mocked<Logger>; + +describe('api_sir', () => { + let externalService: jest.Mocked<ExternalServiceSIR>; + + beforeEach(() => { + externalService = externalServiceSIRMock.create(); + jest.clearAllMocks(); + }); + + describe('combineObservables', () => { + test('it returns an empty array when both arguments are an empty array', async () => { + expect(combineObservables([], [])).toEqual([]); + }); + + test('it returns an empty array when both arguments are an empty string', async () => { + expect(combineObservables('', '')).toEqual([]); + }); + + test('it returns an empty array when a="" and b=[]', async () => { + expect(combineObservables('', [])).toEqual([]); + }); + + test('it returns an empty array when a=[] and b=""', async () => { + expect(combineObservables([], '')).toEqual([]); + }); + + test('it returns a if b is empty', async () => { + expect(combineObservables('a', '')).toEqual(['a']); + }); + + test('it returns b if a is empty', async () => { + expect(combineObservables([], ['b'])).toEqual(['b']); + }); + + test('it combines two strings', async () => { + expect(combineObservables('a,b', 'c,d')).toEqual(['a', 'b', 'c', 'd']); + }); + + test('it combines two arrays', async () => { + expect(combineObservables(['a'], ['b'])).toEqual(['a', 'b']); + }); + + test('it combines a string with an array', async () => { + expect(combineObservables('a', ['b'])).toEqual(['a', 'b']); + }); + + test('it combines an array with a string ', async () => { + expect(combineObservables(['a'], 'b')).toEqual(['a', 'b']); + }); + + test('it combines a "," concatenated string', async () => { + expect(combineObservables(['a'], 'b,c,d')).toEqual(['a', 'b', 'c', 'd']); + expect(combineObservables('b,c,d', ['a'])).toEqual(['b', 'c', 'd', 'a']); + }); + + test('it combines a "|" concatenated string', async () => { + expect(combineObservables(['a'], 'b|c|d')).toEqual(['a', 'b', 'c', 'd']); + expect(combineObservables('b|c|d', ['a'])).toEqual(['b', 'c', 'd', 'a']); + }); + + test('it combines a space concatenated string', async () => { + expect(combineObservables(['a'], 'b c d')).toEqual(['a', 'b', 'c', 'd']); + expect(combineObservables('b c d', ['a'])).toEqual(['b', 'c', 'd', 'a']); + }); + + test('it combines a "\\n" concatenated string', async () => { + expect(combineObservables(['a'], 'b\nc\nd')).toEqual(['a', 'b', 'c', 'd']); + expect(combineObservables('b\nc\nd', ['a'])).toEqual(['b', 'c', 'd', 'a']); + }); + + test('it combines a "\\r" concatenated string', async () => { + expect(combineObservables(['a'], 'b\rc\rd')).toEqual(['a', 'b', 'c', 'd']); + expect(combineObservables('b\rc\rd', ['a'])).toEqual(['b', 'c', 'd', 'a']); + }); + + test('it combines a "\\t" concatenated string', async () => { + expect(combineObservables(['a'], 'b\tc\td')).toEqual(['a', 'b', 'c', 'd']); + expect(combineObservables('b\tc\td', ['a'])).toEqual(['b', 'c', 'd', 'a']); + }); + + test('it combines two strings with different delimiter', async () => { + expect(combineObservables('a|b|c', 'd e f')).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); + }); + }); + + describe('formatObservables', () => { + test('it formats array observables correctly', async () => { + const expectedTypes: Array<[ObservableTypes, string]> = [ + [ObservableTypes.ip4, 'ipv4-addr'], + [ObservableTypes.sha256, 'SHA256'], + [ObservableTypes.url, 'URL'], + ]; + + for (const type of expectedTypes) { + expect(formatObservables(['a', 'b', 'c'], type[0])).toEqual([ + { type: type[1], value: 'a' }, + { type: type[1], value: 'b' }, + { type: type[1], value: 'c' }, + ]); + } + }); + + test('it removes duplicates from array observables correctly', async () => { + expect(formatObservables(['a', 'a', 'c'], ObservableTypes.ip4)).toEqual([ + { type: 'ipv4-addr', value: 'a' }, + { type: 'ipv4-addr', value: 'c' }, + ]); + }); + + test('it formats an empty array correctly', async () => { + expect(formatObservables([], ObservableTypes.ip4)).toEqual([]); + }); + + test('it removes empty observables correctly', async () => { + expect(formatObservables(['a', '', 'c'], ObservableTypes.ip4)).toEqual([ + { type: 'ipv4-addr', value: 'a' }, + { type: 'ipv4-addr', value: 'c' }, + ]); + }); + }); + + describe('prepareParams', () => { + test('it prepares the params correctly when the connector is legacy', async () => { + expect(prepareParams(true, sirParams)).toEqual({ + ...sirParams, + incident: { + ...sirParams.incident, + dest_ip: '192.168.1.1,192.168.1.3', + source_ip: '192.168.1.2,192.168.1.4', + malware_hash: '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9', + malware_url: 'https://example.com', + }, + }); + }); + + test('it prepares the params correctly when the connector is not legacy', async () => { + expect(prepareParams(false, sirParams)).toEqual({ + ...sirParams, + incident: { + ...sirParams.incident, + dest_ip: null, + source_ip: null, + malware_hash: null, + malware_url: null, + }, + }); + }); + + test('it prepares the params correctly when the connector is legacy and the observables are undefined', async () => { + const { + dest_ip: destIp, + source_ip: sourceIp, + malware_hash: malwareHash, + malware_url: malwareURL, + ...incidentWithoutObservables + } = sirParams.incident; + + expect( + prepareParams(true, { + ...sirParams, + // @ts-expect-error + incident: incidentWithoutObservables, + }) + ).toEqual({ + ...sirParams, + incident: { + ...sirParams.incident, + dest_ip: null, + source_ip: null, + malware_hash: null, + malware_url: null, + }, + }); + }); + }); + + describe('pushToService', () => { + test('it creates an incident correctly', async () => { + const params = { ...sirParams, incident: { ...sirParams.incident, externalId: null } }; + const res = await apiSIR.pushToService({ + externalService, + params, + config: { isLegacy: false }, + secrets: {}, + logger: mockedLogger, + commentFieldKey: 'work_notes', + }); + + expect(res).toEqual({ + id: 'incident-1', + title: 'INC01', + pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://instance.service-now.com/nav_to.do?uri=incident.do?sys_id=123', + comments: [ + { + commentId: 'case-comment-1', + pushedDate: '2020-03-10T12:24:20.000Z', + }, + { + commentId: 'case-comment-2', + pushedDate: '2020-03-10T12:24:20.000Z', + }, + ], + }); + }); + + test('it adds observables correctly', async () => { + const params = { ...sirParams, incident: { ...sirParams.incident, externalId: null } }; + await apiSIR.pushToService({ + externalService, + params, + config: { isLegacy: false }, + secrets: {}, + logger: mockedLogger, + commentFieldKey: 'work_notes', + }); + + expect(externalService.bulkAddObservableToIncident).toHaveBeenCalledWith( + [ + { type: 'ipv4-addr', value: '192.168.1.1' }, + { type: 'ipv4-addr', value: '192.168.1.3' }, + { type: 'ipv4-addr', value: '192.168.1.2' }, + { type: 'ipv4-addr', value: '192.168.1.4' }, + { + type: 'SHA256', + value: '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9', + }, + { type: 'URL', value: 'https://example.com' }, + ], + // createIncident mock returns this incident id + 'incident-1' + ); + }); + + test('it does not call bulkAddObservableToIncident if it a legacy connector', async () => { + const params = { ...sirParams, incident: { ...sirParams.incident, externalId: null } }; + await apiSIR.pushToService({ + externalService, + params, + config: { isLegacy: true }, + secrets: {}, + logger: mockedLogger, + commentFieldKey: 'work_notes', + }); + + expect(externalService.bulkAddObservableToIncident).not.toHaveBeenCalled(); + }); + + test('it does not call bulkAddObservableToIncident if there are no observables', async () => { + const params = { + ...sirParams, + incident: { + ...sirParams.incident, + dest_ip: null, + source_ip: null, + malware_hash: null, + malware_url: null, + externalId: null, + }, + }; + + await apiSIR.pushToService({ + externalService, + params, + config: { isLegacy: false }, + secrets: {}, + logger: mockedLogger, + commentFieldKey: 'work_notes', + }); + + expect(externalService.bulkAddObservableToIncident).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.ts new file mode 100644 index 0000000000000..326bb79a0e708 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.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 { isEmpty, isString } from 'lodash'; + +import { + ExecutorSubActionPushParamsSIR, + ExternalServiceAPI, + ExternalServiceSIR, + ObservableTypes, + PushToServiceApiHandlerArgs, + PushToServiceApiParamsSIR, + PushToServiceResponse, +} from './types'; + +import { api } from './api'; + +const SPLIT_REGEX = /[ ,|\r\n\t]+/; + +export const formatObservables = (observables: string[], type: ObservableTypes) => { + /** + * ServiceNow accepted formats are: comma, new line, tab, or pipe separators. + * Before the application the observables were being sent to ServiceNow as a concatenated string with + * delimiter. With the application the format changed to an array of observables. + */ + const uniqueObservables = new Set(observables); + return [...uniqueObservables].filter((obs) => !isEmpty(obs)).map((obs) => ({ value: obs, type })); +}; + +const obsAsArray = (obs: string | string[]): string[] => { + if (isEmpty(obs)) { + return []; + } + + if (isString(obs)) { + return obs.split(SPLIT_REGEX); + } + + return obs; +}; + +export const combineObservables = (a: string | string[], b: string | string[]): string[] => { + const first = obsAsArray(a); + const second = obsAsArray(b); + + return [...first, ...second]; +}; + +const observablesToString = (obs: string | string[] | null | undefined): string | null => { + if (Array.isArray(obs)) { + return obs.join(','); + } + + return obs ?? null; +}; + +export const prepareParams = ( + isLegacy: boolean, + params: PushToServiceApiParamsSIR +): PushToServiceApiParamsSIR => { + if (isLegacy) { + /** + * The schema has change to accept an array of observables + * or a string. In the case of a legacy connector we need to + * convert the observables to a string + */ + return { + ...params, + incident: { + ...params.incident, + dest_ip: observablesToString(params.incident.dest_ip), + malware_hash: observablesToString(params.incident.malware_hash), + malware_url: observablesToString(params.incident.malware_url), + source_ip: observablesToString(params.incident.source_ip), + }, + }; + } + + /** + * For non legacy connectors the observables + * will be added in a different call. + * They need to be set to null when sending the fields + * to ServiceNow + */ + return { + ...params, + incident: { + ...params.incident, + dest_ip: null, + malware_hash: null, + malware_url: null, + source_ip: null, + }, + }; +}; + +const pushToServiceHandler = async ({ + externalService, + params, + config, + secrets, + commentFieldKey, + logger, +}: PushToServiceApiHandlerArgs): Promise<PushToServiceResponse> => { + const res = await api.pushToService({ + externalService, + params: prepareParams(!!config.isLegacy, params as PushToServiceApiParamsSIR), + config, + secrets, + commentFieldKey, + logger, + }); + + const { + incident: { + dest_ip: destIP, + malware_hash: malwareHash, + malware_url: malwareUrl, + source_ip: sourceIP, + }, + } = params as ExecutorSubActionPushParamsSIR; + + /** + * Add bulk observables is only available for new connectors + * Old connectors gonna add their observables + * through the pushToService call. + */ + + if (!config.isLegacy) { + const sirExternalService = externalService as ExternalServiceSIR; + + const obsWithType: Array<[string[], ObservableTypes]> = [ + [combineObservables(destIP ?? [], sourceIP ?? []), ObservableTypes.ip4], + [obsAsArray(malwareHash ?? []), ObservableTypes.sha256], + [obsAsArray(malwareUrl ?? []), ObservableTypes.url], + ]; + + const observables = obsWithType.map(([obs, type]) => formatObservables(obs, type)).flat(); + if (observables.length > 0) { + await sirExternalService.bulkAddObservableToIncident(observables, res.id); + } + } + + return res; +}; + +export const apiSIR: ExternalServiceAPI = { + ...api, + pushToService: pushToServiceHandler, +}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts new file mode 100644 index 0000000000000..babd360cbcb82 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { snExternalServiceConfig } from './config'; + +/** + * The purpose of this test is to + * prevent developers from accidentally + * change important configuration values + * such as the scope or the import set table + * of our ServiceNow application + */ + +describe('config', () => { + test('ITSM: the config are correct', async () => { + const snConfig = snExternalServiceConfig['.servicenow']; + expect(snConfig).toEqual({ + importSetTable: 'x_elas2_inc_int_elastic_incident', + appScope: 'x_elas2_inc_int', + table: 'incident', + useImportAPI: true, + commentFieldKey: 'work_notes', + }); + }); + + test('SIR: the config are correct', async () => { + const snConfig = snExternalServiceConfig['.servicenow-sir']; + expect(snConfig).toEqual({ + importSetTable: 'x_elas2_sir_int_elastic_si_incident', + appScope: 'x_elas2_sir_int', + table: 'sn_si_incident', + useImportAPI: true, + commentFieldKey: 'work_notes', + }); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts new file mode 100644 index 0000000000000..37e4c6994b403 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.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 { + ENABLE_NEW_SN_ITSM_CONNECTOR, + ENABLE_NEW_SN_SIR_CONNECTOR, +} from '../../constants/connectors'; +import { SNProductsConfig } from './types'; + +export const serviceNowITSMTable = 'incident'; +export const serviceNowSIRTable = 'sn_si_incident'; + +export const ServiceNowITSMActionTypeId = '.servicenow'; +export const ServiceNowSIRActionTypeId = '.servicenow-sir'; + +export const snExternalServiceConfig: SNProductsConfig = { + '.servicenow': { + importSetTable: 'x_elas2_inc_int_elastic_incident', + appScope: 'x_elas2_inc_int', + table: 'incident', + useImportAPI: ENABLE_NEW_SN_ITSM_CONNECTOR, + commentFieldKey: 'work_notes', + }, + '.servicenow-sir': { + importSetTable: 'x_elas2_sir_int_elastic_si_incident', + appScope: 'x_elas2_sir_int', + table: 'sn_si_incident', + useImportAPI: ENABLE_NEW_SN_SIR_CONNECTOR, + commentFieldKey: 'work_notes', + }, +}; + +export const FIELD_PREFIX = 'u_'; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index f2b500df6ccb3..29907381d45da 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -18,7 +18,7 @@ import { import { ActionsConfigurationUtilities } from '../../actions_config'; import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../../types'; import { createExternalService } from './service'; -import { api } from './api'; +import { api as commonAPI } from './api'; import * as i18n from './translations'; import { Logger } from '../../../../../../src/core/server'; import { @@ -30,7 +30,25 @@ import { ExecutorSubActionCommonFieldsParams, ServiceNowExecutorResultData, ExecutorSubActionGetChoicesParams, + ServiceFactory, + ExternalServiceAPI, } from './types'; +import { + ServiceNowITSMActionTypeId, + serviceNowITSMTable, + ServiceNowSIRActionTypeId, + serviceNowSIRTable, + snExternalServiceConfig, +} from './config'; +import { createExternalServiceSIR } from './service_sir'; +import { apiSIR } from './api_sir'; + +export { + ServiceNowITSMActionTypeId, + serviceNowITSMTable, + ServiceNowSIRActionTypeId, + serviceNowSIRTable, +}; export type ActionParamsType = | TypeOf<typeof ExecutorParamsSchemaITSM> @@ -41,12 +59,6 @@ interface GetActionTypeParams { configurationUtilities: ActionsConfigurationUtilities; } -const serviceNowITSMTable = 'incident'; -const serviceNowSIRTable = 'sn_si_incident'; - -export const ServiceNowITSMActionTypeId = '.servicenow'; -export const ServiceNowSIRActionTypeId = '.servicenow-sir'; - export type ServiceNowActionType = ActionType< ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType, @@ -79,8 +91,9 @@ export function getServiceNowITSMActionType(params: GetActionTypeParams): Servic executor: curry(executor)({ logger, configurationUtilities, - table: serviceNowITSMTable, - commentFieldKey: 'work_notes', + actionTypeId: ServiceNowITSMActionTypeId, + createService: createExternalService, + api: commonAPI, }), }; } @@ -103,8 +116,9 @@ export function getServiceNowSIRActionType(params: GetActionTypeParams): Service executor: curry(executor)({ logger, configurationUtilities, - table: serviceNowSIRTable, - commentFieldKey: 'work_notes', + actionTypeId: ServiceNowSIRActionTypeId, + createService: createExternalServiceSIR, + api: apiSIR, }), }; } @@ -115,28 +129,31 @@ async function executor( { logger, configurationUtilities, - table, - commentFieldKey = 'comments', + actionTypeId, + createService, + api, }: { logger: Logger; configurationUtilities: ActionsConfigurationUtilities; - table: string; - commentFieldKey?: string; + actionTypeId: string; + createService: ServiceFactory; + api: ExternalServiceAPI; }, execOptions: ServiceNowActionTypeExecutorOptions ): Promise<ActionTypeExecutorResult<ServiceNowExecutorResultData | {}>> { const { actionId, config, params, secrets } = execOptions; const { subAction, subActionParams } = params; + const externalServiceConfig = snExternalServiceConfig[actionTypeId]; let data: ServiceNowExecutorResultData | null = null; - const externalService = createExternalService( - table, + const externalService = createService( { config, secrets, }, logger, - configurationUtilities + configurationUtilities, + externalServiceConfig ); if (!api[subAction]) { @@ -156,9 +173,10 @@ async function executor( data = await api.pushToService({ externalService, params: pushToServiceParams, + config, secrets, logger, - commentFieldKey, + commentFieldKey: externalServiceConfig.commentFieldKey, }); logger.debug(`response push to service for incident id: ${data.id}`); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts index 909200472be33..3629fb33915ae 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts @@ -5,7 +5,14 @@ * 2.0. */ -import { ExternalService, ExecutorSubActionPushParams } from './types'; +import { + ExternalService, + ExecutorSubActionPushParams, + PushToServiceApiParamsSIR, + ExternalServiceSIR, + Observable, + ObservableTypes, +} from './types'; export const serviceNowCommonFields = [ { @@ -74,6 +81,10 @@ const createMock = (): jest.Mocked<ExternalService> => { getFields: jest.fn().mockImplementation(() => Promise.resolve(serviceNowCommonFields)), getIncident: jest.fn().mockImplementation(() => Promise.resolve({ + id: 'incident-1', + title: 'INC01', + pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://instance.service-now.com/nav_to.do?uri=incident.do?sys_id=123', short_description: 'title from servicenow', description: 'description from servicenow', }) @@ -95,16 +106,60 @@ const createMock = (): jest.Mocked<ExternalService> => { }) ), findIncidents: jest.fn(), + getApplicationInformation: jest.fn().mockImplementation(() => + Promise.resolve({ + name: 'Elastic', + scope: 'x_elas2_inc_int', + version: '1.0.0', + }) + ), + checkIfApplicationIsInstalled: jest.fn(), + getUrl: jest.fn().mockImplementation(() => 'https://instance.service-now.com'), + checkInstance: jest.fn(), }; return service; }; -const externalServiceMock = { +const createSIRMock = (): jest.Mocked<ExternalServiceSIR> => { + const service = { + ...createMock(), + addObservableToIncident: jest.fn().mockImplementation(() => + Promise.resolve({ + value: 'https://example.com', + observable_sys_id: '3', + }) + ), + bulkAddObservableToIncident: jest.fn().mockImplementation(() => + Promise.resolve([ + { + value: '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9', + observable_sys_id: '1', + }, + { + value: '127.0.0.1', + observable_sys_id: '2', + }, + { + value: 'https://example.com', + observable_sys_id: '3', + }, + ]) + ), + }; + + return service; +}; + +export const externalServiceMock = { create: createMock, }; -const executorParams: ExecutorSubActionPushParams = { +export const externalServiceSIRMock = { + create: createSIRMock, +}; + +export const executorParams: ExecutorSubActionPushParams = { incident: { externalId: 'incident-3', short_description: 'Incident title', @@ -114,6 +169,8 @@ const executorParams: ExecutorSubActionPushParams = { impact: '3', category: 'software', subcategory: 'os', + correlation_id: 'ruleId', + correlation_display: 'Alerting', }, comments: [ { @@ -127,6 +184,46 @@ const executorParams: ExecutorSubActionPushParams = { ], }; -const apiParams = executorParams; +export const sirParams: PushToServiceApiParamsSIR = { + incident: { + externalId: 'incident-3', + short_description: 'Incident title', + description: 'Incident description', + dest_ip: ['192.168.1.1', '192.168.1.3'], + source_ip: ['192.168.1.2', '192.168.1.4'], + malware_hash: ['5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9'], + malware_url: ['https://example.com'], + category: 'software', + subcategory: 'os', + correlation_id: 'ruleId', + correlation_display: 'Alerting', + priority: '1', + }, + comments: [ + { + commentId: 'case-comment-1', + comment: 'A comment', + }, + { + commentId: 'case-comment-2', + comment: 'Another comment', + }, + ], +}; + +export const observables: Observable[] = [ + { + value: '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9', + type: ObservableTypes.sha256, + }, + { + value: '127.0.0.1', + type: ObservableTypes.ip4, + }, + { + value: 'https://example.com', + type: ObservableTypes.url, + }, +]; -export { externalServiceMock, executorParams, apiParams }; +export const apiParams = executorParams; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index 6fec30803d6d7..dab68bb9d3e9d 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; export const ExternalIncidentServiceConfiguration = { apiUrl: schema.string(), + isLegacy: schema.boolean({ defaultValue: false }), }; export const ExternalIncidentServiceConfigurationSchema = schema.object( @@ -39,6 +40,8 @@ const CommonAttributes = { externalId: schema.nullable(schema.string()), category: schema.nullable(schema.string()), subcategory: schema.nullable(schema.string()), + correlation_id: schema.nullable(schema.string()), + correlation_display: schema.nullable(schema.string()), }; // Schema for ServiceNow Incident Management (ITSM) @@ -56,10 +59,22 @@ export const ExecutorSubActionPushParamsSchemaITSM = schema.object({ export const ExecutorSubActionPushParamsSchemaSIR = schema.object({ incident: schema.object({ ...CommonAttributes, - dest_ip: schema.nullable(schema.string()), - malware_hash: schema.nullable(schema.string()), - malware_url: schema.nullable(schema.string()), - source_ip: schema.nullable(schema.string()), + dest_ip: schema.oneOf( + [schema.nullable(schema.string()), schema.nullable(schema.arrayOf(schema.string()))], + { defaultValue: null } + ), + malware_hash: schema.oneOf( + [schema.nullable(schema.string()), schema.nullable(schema.arrayOf(schema.string()))], + { defaultValue: null } + ), + malware_url: schema.oneOf( + [schema.nullable(schema.string()), schema.nullable(schema.arrayOf(schema.string()))], + { defaultValue: null } + ), + source_ip: schema.oneOf( + [schema.nullable(schema.string()), schema.nullable(schema.arrayOf(schema.string()))], + { defaultValue: null } + ), priority: schema.nullable(schema.string()), }), comments: CommentsSchema, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts index 37bfb662508a2..b8499b01e6a02 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts @@ -5,15 +5,16 @@ * 2.0. */ -import axios from 'axios'; +import axios, { AxiosResponse } from 'axios'; import { createExternalService } from './service'; import * as utils from '../lib/axios_utils'; -import { ExternalService } from './types'; +import { ExternalService, ServiceNowITSMIncident } from './types'; import { Logger } from '../../../../../../src/core/server'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; import { actionsConfigMock } from '../../actions_config.mock'; import { serviceNowCommonFields, serviceNowChoices } from './mocks'; +import { snExternalServiceConfig } from './config'; const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>; jest.mock('axios'); @@ -28,24 +29,134 @@ jest.mock('../lib/axios_utils', () => { axios.create = jest.fn(() => axios); const requestMock = utils.request as jest.Mock; -const patchMock = utils.patch as jest.Mock; const configurationUtilities = actionsConfigMock.create(); -const table = 'incident'; + +const getImportSetAPIResponse = (update = false) => ({ + import_set: 'ISET01', + staging_table: 'x_elas2_inc_int_elastic_incident', + result: [ + { + transform_map: 'Elastic Incident', + table: 'incident', + display_name: 'number', + display_value: 'INC01', + record_link: 'https://example.com/api/now/table/incident/1', + status: update ? 'updated' : 'inserted', + sys_id: '1', + }, + ], +}); + +const getImportSetAPIError = () => ({ + import_set: 'ISET01', + staging_table: 'x_elas2_inc_int_elastic_incident', + result: [ + { + transform_map: 'Elastic Incident', + status: 'error', + error_message: 'An error has occurred while importing the incident', + status_message: 'failure', + }, + ], +}); + +const mockApplicationVersion = () => + requestMock.mockImplementationOnce(() => ({ + data: { + result: { name: 'Elastic', scope: 'x_elas2_inc_int', version: '1.0.0' }, + }, + })); + +const mockImportIncident = (update: boolean) => + requestMock.mockImplementationOnce(() => ({ + data: getImportSetAPIResponse(update), + })); + +const mockIncidentResponse = (update: boolean) => + requestMock.mockImplementation(() => ({ + data: { + result: { + sys_id: '1', + number: 'INC01', + ...(update + ? { sys_updated_on: '2020-03-10 12:24:20' } + : { sys_created_on: '2020-03-10 12:24:20' }), + }, + }, + })); + +const createIncident = async (service: ExternalService) => { + // Get application version + mockApplicationVersion(); + // Import set api response + mockImportIncident(false); + // Get incident response + mockIncidentResponse(false); + + return await service.createIncident({ + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }); +}; + +const updateIncident = async (service: ExternalService) => { + // Get application version + mockApplicationVersion(); + // Import set api response + mockImportIncident(true); + // Get incident response + mockIncidentResponse(true); + + return await service.updateIncident({ + incidentId: '1', + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }); +}; + +const expectImportedIncident = (update: boolean) => { + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/x_elas2_inc_int/elastic_api/health', + method: 'get', + }); + + expect(requestMock).toHaveBeenNthCalledWith(2, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/import/x_elas2_inc_int_elastic_incident', + method: 'post', + data: { + u_short_description: 'title', + u_description: 'desc', + ...(update ? { elastic_incident_id: '1' } : {}), + }, + }); + + expect(requestMock).toHaveBeenNthCalledWith(3, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/incident/1', + method: 'get', + }); +}; describe('ServiceNow service', () => { let service: ExternalService; beforeEach(() => { service = createExternalService( - table, { // The trailing slash at the end of the url is intended. // All API calls need to have the trailing slash removed. - config: { apiUrl: 'https://dev102283.service-now.com/' }, + config: { apiUrl: 'https://example.com/' }, secrets: { username: 'admin', password: 'admin' }, }, logger, - configurationUtilities + configurationUtilities, + snExternalServiceConfig['.servicenow'] ); }); @@ -57,13 +168,13 @@ describe('ServiceNow service', () => { test('throws without url', () => { expect(() => createExternalService( - table, { config: { apiUrl: null }, secrets: { username: 'admin', password: 'admin' }, }, logger, - configurationUtilities + configurationUtilities, + snExternalServiceConfig['.servicenow'] ) ).toThrow(); }); @@ -71,13 +182,13 @@ describe('ServiceNow service', () => { test('throws without username', () => { expect(() => createExternalService( - table, { config: { apiUrl: 'test.com' }, secrets: { username: '', password: 'admin' }, }, logger, - configurationUtilities + configurationUtilities, + snExternalServiceConfig['.servicenow'] ) ).toThrow(); }); @@ -85,13 +196,13 @@ describe('ServiceNow service', () => { test('throws without password', () => { expect(() => createExternalService( - table, { config: { apiUrl: 'test.com' }, secrets: { username: '', password: undefined }, }, logger, - configurationUtilities + configurationUtilities, + snExternalServiceConfig['.servicenow'] ) ).toThrow(); }); @@ -116,19 +227,20 @@ describe('ServiceNow service', () => { axios, logger, configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/incident/1', + url: 'https://example.com/api/now/v2/table/incident/1', + method: 'get', }); }); test('it should call request with correct arguments when table changes', async () => { service = createExternalService( - 'sn_si_incident', { - config: { apiUrl: 'https://dev102283.service-now.com/' }, + config: { apiUrl: 'https://example.com/' }, secrets: { username: 'admin', password: 'admin' }, }, logger, - configurationUtilities + configurationUtilities, + { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' } ); requestMock.mockImplementation(() => ({ @@ -140,7 +252,8 @@ describe('ServiceNow service', () => { axios, logger, configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sn_si_incident/1', + url: 'https://example.com/api/now/v2/table/sn_si_incident/1', + method: 'get', }); }); @@ -166,214 +279,346 @@ describe('ServiceNow service', () => { }); describe('createIncident', () => { - test('it creates the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_created_on: '2020-03-10 12:24:20' } }, - })); - - const res = await service.createIncident({ - incident: { short_description: 'title', description: 'desc' }, + // new connectors + describe('import set table', () => { + test('it creates the incident correctly', async () => { + const res = await createIncident(service); + expect(res).toEqual({ + title: 'INC01', + id: '1', + pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://example.com/nav_to.do?uri=incident.do?sys_id=1', + }); }); - expect(res).toEqual({ - title: 'INC01', - id: '1', - pushedDate: '2020-03-10T12:24:20.000Z', - url: 'https://dev102283.service-now.com/nav_to.do?uri=incident.do?sys_id=1', + test('it should call request with correct arguments', async () => { + await createIncident(service); + expect(requestMock).toHaveBeenCalledTimes(3); + expectImportedIncident(false); }); - }); - test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_created_on: '2020-03-10 12:24:20' } }, - })); + test('it should call request with correct arguments when table changes', async () => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + snExternalServiceConfig['.servicenow-sir'] + ); - await service.createIncident({ - incident: { short_description: 'title', description: 'desc' }, - }); + const res = await createIncident(service); - expect(requestMock).toHaveBeenCalledWith({ - axios, - logger, - configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/incident', - method: 'post', - data: { short_description: 'title', description: 'desc' }, - }); - }); + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', + method: 'get', + }); - test('it should call request with correct arguments when table changes', async () => { - service = createExternalService( - 'sn_si_incident', - { - config: { apiUrl: 'https://dev102283.service-now.com/' }, - secrets: { username: 'admin', password: 'admin' }, - }, - logger, - configurationUtilities - ); + expect(requestMock).toHaveBeenNthCalledWith(2, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/import/x_elas2_sir_int_elastic_si_incident', + method: 'post', + data: { u_short_description: 'title', u_description: 'desc' }, + }); + + expect(requestMock).toHaveBeenNthCalledWith(3, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/sn_si_incident/1', + method: 'get', + }); - requestMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_created_on: '2020-03-10 12:24:20' } }, - })); + expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); + }); - const res = await service.createIncident({ - incident: { short_description: 'title', description: 'desc' }, + test('it should throw an error when the application is not installed', async () => { + requestMock.mockImplementation(() => { + throw new Error('An error has occurred'); + }); + + await expect( + service.createIncident({ + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }) + ).rejects.toThrow( + '[Action][ServiceNow]: Unable to create incident. Error: [Action][ServiceNow]: Unable to get application version. Error: An error has occurred Reason: unknown: errorResponse was null Reason: unknown: errorResponse was null' + ); }); - expect(requestMock).toHaveBeenCalledWith({ - axios, - logger, - configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sn_si_incident', - method: 'post', - data: { short_description: 'title', description: 'desc' }, + test('it should throw an error when instance is not alive', async () => { + requestMock.mockImplementation(() => ({ + status: 200, + data: {}, + request: { connection: { servername: 'Developer instance' } }, + })); + await expect( + service.createIncident({ + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }) + ).rejects.toThrow( + 'There is an issue with your Service Now Instance. Please check Developer instance.' + ); }); - expect(res.url).toEqual( - 'https://dev102283.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=1' - ); + test('it should throw an error when there is an import set api error', async () => { + requestMock.mockImplementation(() => ({ data: getImportSetAPIError() })); + await expect( + service.createIncident({ + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }) + ).rejects.toThrow( + '[Action][ServiceNow]: Unable to create incident. Error: An error has occurred while importing the incident Reason: unknown' + ); + }); }); - test('it should throw an error', async () => { - requestMock.mockImplementation(() => { - throw new Error('An error has occurred'); + // old connectors + describe('table API', () => { + beforeEach(() => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + { ...snExternalServiceConfig['.servicenow'], useImportAPI: false } + ); }); - await expect( - service.createIncident({ - incident: { short_description: 'title', description: 'desc' }, - }) - ).rejects.toThrow( - '[Action][ServiceNow]: Unable to create incident. Error: An error has occurred' - ); - }); + test('it creates the incident correctly', async () => { + mockIncidentResponse(false); + const res = await service.createIncident({ + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }); + + expect(res).toEqual({ + title: 'INC01', + id: '1', + pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://example.com/nav_to.do?uri=incident.do?sys_id=1', + }); + + expect(requestMock).toHaveBeenCalledTimes(2); + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/incident', + method: 'post', + data: { short_description: 'title', description: 'desc' }, + }); + }); - test('it should throw an error when instance is not alive', async () => { - requestMock.mockImplementation(() => ({ - status: 200, - data: {}, - request: { connection: { servername: 'Developer instance' } }, - })); - await expect(service.getIncident('1')).rejects.toThrow( - 'There is an issue with your Service Now Instance. Please check Developer instance.' - ); - }); - }); + test('it should call request with correct arguments when table changes', async () => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false } + ); - describe('updateIncident', () => { - test('it updates the incident correctly', async () => { - patchMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_updated_on: '2020-03-10 12:24:20' } }, - })); + mockIncidentResponse(false); - const res = await service.updateIncident({ - incidentId: '1', - incident: { short_description: 'title', description: 'desc' }, - }); + const res = await service.createIncident({ + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }); + + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/sn_si_incident', + method: 'post', + data: { short_description: 'title', description: 'desc' }, + }); - expect(res).toEqual({ - title: 'INC01', - id: '1', - pushedDate: '2020-03-10T12:24:20.000Z', - url: 'https://dev102283.service-now.com/nav_to.do?uri=incident.do?sys_id=1', + expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); }); }); + }); - test('it should call request with correct arguments', async () => { - patchMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_updated_on: '2020-03-10 12:24:20' } }, - })); - - await service.updateIncident({ - incidentId: '1', - incident: { short_description: 'title', description: 'desc' }, + describe('updateIncident', () => { + // new connectors + describe('import set table', () => { + test('it updates the incident correctly', async () => { + const res = await updateIncident(service); + + expect(res).toEqual({ + title: 'INC01', + id: '1', + pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://example.com/nav_to.do?uri=incident.do?sys_id=1', + }); }); - expect(patchMock).toHaveBeenCalledWith({ - axios, - logger, - configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/incident/1', - data: { short_description: 'title', description: 'desc' }, + test('it should call request with correct arguments', async () => { + await updateIncident(service); + expectImportedIncident(true); }); - }); - test('it should call request with correct arguments when table changes', async () => { - service = createExternalService( - 'sn_si_incident', - { - config: { apiUrl: 'https://dev102283.service-now.com/' }, - secrets: { username: 'admin', password: 'admin' }, - }, - logger, - configurationUtilities - ); + test('it should call request with correct arguments when table changes', async () => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + snExternalServiceConfig['.servicenow-sir'] + ); - patchMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_updated_on: '2020-03-10 12:24:20' } }, - })); + const res = await updateIncident(service); + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', + method: 'get', + }); - const res = await service.updateIncident({ - incidentId: '1', - incident: { short_description: 'title', description: 'desc' }, + expect(requestMock).toHaveBeenNthCalledWith(2, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/import/x_elas2_sir_int_elastic_si_incident', + method: 'post', + data: { u_short_description: 'title', u_description: 'desc', elastic_incident_id: '1' }, + }); + + expect(requestMock).toHaveBeenNthCalledWith(3, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/sn_si_incident/1', + method: 'get', + }); + + expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); }); - expect(patchMock).toHaveBeenCalledWith({ - axios, - logger, - configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sn_si_incident/1', - data: { short_description: 'title', description: 'desc' }, + test('it should throw an error when the application is not installed', async () => { + requestMock.mockImplementation(() => { + throw new Error('An error has occurred'); + }); + + await expect( + service.updateIncident({ + incidentId: '1', + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }) + ).rejects.toThrow( + '[Action][ServiceNow]: Unable to update incident with id 1. Error: [Action][ServiceNow]: Unable to get application version. Error: An error has occurred Reason: unknown: errorResponse was null Reason: unknown: errorResponse was null' + ); }); - expect(res.url).toEqual( - 'https://dev102283.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=1' - ); + test('it should throw an error when instance is not alive', async () => { + requestMock.mockImplementation(() => ({ + status: 200, + data: {}, + request: { connection: { servername: 'Developer instance' } }, + })); + await expect( + service.updateIncident({ + incidentId: '1', + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }) + ).rejects.toThrow( + 'There is an issue with your Service Now Instance. Please check Developer instance.' + ); + }); + + test('it should throw an error when there is an import set api error', async () => { + requestMock.mockImplementation(() => ({ data: getImportSetAPIError() })); + await expect( + service.updateIncident({ + incidentId: '1', + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }) + ).rejects.toThrow( + '[Action][ServiceNow]: Unable to update incident with id 1. Error: An error has occurred while importing the incident Reason: unknown' + ); + }); }); - test('it should throw an error', async () => { - patchMock.mockImplementation(() => { - throw new Error('An error has occurred'); + // old connectors + describe('table API', () => { + beforeEach(() => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + { ...snExternalServiceConfig['.servicenow'], useImportAPI: false } + ); }); - await expect( - service.updateIncident({ + test('it updates the incident correctly', async () => { + mockIncidentResponse(true); + const res = await service.updateIncident({ incidentId: '1', - incident: { short_description: 'title', description: 'desc' }, - }) - ).rejects.toThrow( - '[Action][ServiceNow]: Unable to update incident with id 1. Error: An error has occurred' - ); - }); + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }); + + expect(res).toEqual({ + title: 'INC01', + id: '1', + pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://example.com/nav_to.do?uri=incident.do?sys_id=1', + }); + + expect(requestMock).toHaveBeenCalledTimes(2); + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/incident/1', + method: 'patch', + data: { short_description: 'title', description: 'desc' }, + }); + }); - test('it creates the comment correctly', async () => { - patchMock.mockImplementation(() => ({ - data: { result: { sys_id: '11', number: 'INC011', sys_updated_on: '2020-03-10 12:24:20' } }, - })); + test('it should call request with correct arguments when table changes', async () => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + { ...snExternalServiceConfig['.servicenow-sir'], useImportAPI: false } + ); - const res = await service.updateIncident({ - incidentId: '1', - comment: 'comment-1', - }); + mockIncidentResponse(false); - expect(res).toEqual({ - title: 'INC011', - id: '11', - pushedDate: '2020-03-10T12:24:20.000Z', - url: 'https://dev102283.service-now.com/nav_to.do?uri=incident.do?sys_id=11', - }); - }); + const res = await service.updateIncident({ + incidentId: '1', + incident: { short_description: 'title', description: 'desc' } as ServiceNowITSMIncident, + }); - test('it should throw an error when instance is not alive', async () => { - requestMock.mockImplementation(() => ({ - status: 200, - data: {}, - request: { connection: { servername: 'Developer instance' } }, - })); - await expect(service.getIncident('1')).rejects.toThrow( - 'There is an issue with your Service Now Instance. Please check Developer instance.' - ); + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/now/v2/table/sn_si_incident/1', + method: 'patch', + data: { short_description: 'title', description: 'desc' }, + }); + + expect(res.url).toEqual('https://example.com/nav_to.do?uri=sn_si_incident.do?sys_id=1'); + }); }); }); @@ -388,7 +633,7 @@ describe('ServiceNow service', () => { axios, logger, configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sys_dictionary?sysparm_query=name=task^ORname=incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', + url: 'https://example.com/api/now/table/sys_dictionary?sysparm_query=name=task^ORname=incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', }); }); @@ -402,13 +647,13 @@ describe('ServiceNow service', () => { test('it should call request with correct arguments when table changes', async () => { service = createExternalService( - 'sn_si_incident', { - config: { apiUrl: 'https://dev102283.service-now.com/' }, + config: { apiUrl: 'https://example.com/' }, secrets: { username: 'admin', password: 'admin' }, }, logger, - configurationUtilities + configurationUtilities, + { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' } ); requestMock.mockImplementation(() => ({ @@ -420,7 +665,7 @@ describe('ServiceNow service', () => { axios, logger, configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sys_dictionary?sysparm_query=name=task^ORname=sn_si_incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', + url: 'https://example.com/api/now/table/sys_dictionary?sysparm_query=name=task^ORname=sn_si_incident^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory', }); }); @@ -456,7 +701,7 @@ describe('ServiceNow service', () => { axios, logger, configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sys_choice?sysparm_query=name=task^ORname=incident^element=priority^ORelement=category&sysparm_fields=label,value,dependent_value,element', + url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=incident^element=priority^ORelement=category&sysparm_fields=label,value,dependent_value,element', }); }); @@ -470,13 +715,13 @@ describe('ServiceNow service', () => { test('it should call request with correct arguments when table changes', async () => { service = createExternalService( - 'sn_si_incident', { - config: { apiUrl: 'https://dev102283.service-now.com/' }, + config: { apiUrl: 'https://example.com/' }, secrets: { username: 'admin', password: 'admin' }, }, logger, - configurationUtilities + configurationUtilities, + { ...snExternalServiceConfig['.servicenow'], table: 'sn_si_incident' } ); requestMock.mockImplementation(() => ({ @@ -489,7 +734,7 @@ describe('ServiceNow service', () => { axios, logger, configurationUtilities, - url: 'https://dev102283.service-now.com/api/now/v2/table/sys_choice?sysparm_query=name=task^ORname=sn_si_incident^element=priority^ORelement=category&sysparm_fields=label,value,dependent_value,element', + url: 'https://example.com/api/now/table/sys_choice?sysparm_query=name=task^ORname=sn_si_incident^element=priority^ORelement=category&sysparm_fields=label,value,dependent_value,element', }); }); @@ -513,4 +758,79 @@ describe('ServiceNow service', () => { ); }); }); + + describe('getUrl', () => { + test('it returns the instance url', async () => { + expect(service.getUrl()).toBe('https://example.com'); + }); + }); + + describe('checkInstance', () => { + test('it throws an error if there is no result on data', () => { + const res = { status: 200, data: {} } as AxiosResponse; + expect(() => service.checkInstance(res)).toThrow(); + }); + + test('it does NOT throws an error if the status > 400', () => { + const res = { status: 500, data: {} } as AxiosResponse; + expect(() => service.checkInstance(res)).not.toThrow(); + }); + + test('it shows the servername', () => { + const res = { + status: 200, + data: {}, + request: { connection: { servername: 'https://example.com' } }, + } as AxiosResponse; + expect(() => service.checkInstance(res)).toThrow( + 'There is an issue with your Service Now Instance. Please check https://example.com.' + ); + }); + + describe('getApplicationInformation', () => { + test('it returns the application information', async () => { + mockApplicationVersion(); + const res = await service.getApplicationInformation(); + expect(res).toEqual({ + name: 'Elastic', + scope: 'x_elas2_inc_int', + version: '1.0.0', + }); + }); + + test('it should throw an error', async () => { + requestMock.mockImplementation(() => { + throw new Error('An error has occurred'); + }); + await expect(service.getApplicationInformation()).rejects.toThrow( + '[Action][ServiceNow]: Unable to get application version. Error: An error has occurred Reason: unknown' + ); + }); + }); + + describe('checkIfApplicationIsInstalled', () => { + test('it logs the application information', async () => { + mockApplicationVersion(); + await service.checkIfApplicationIsInstalled(); + expect(logger.debug).toHaveBeenCalledWith( + 'Create incident: Application scope: x_elas2_inc_int: Application version1.0.0' + ); + }); + + test('it does not log if useOldApi = true', async () => { + service = createExternalService( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + { ...snExternalServiceConfig['.servicenow'], useImportAPI: false } + ); + await service.checkIfApplicationIsInstalled(); + expect(requestMock).not.toHaveBeenCalled(); + expect(logger.debug).not.toHaveBeenCalled(); + }); + }); + }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index 07ed9edc94d39..cb030c7bb6933 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -7,28 +7,35 @@ import axios, { AxiosResponse } from 'axios'; -import { ExternalServiceCredentials, ExternalService, ExternalServiceParams } from './types'; +import { + ExternalServiceCredentials, + ExternalService, + ExternalServiceParamsCreate, + ExternalServiceParamsUpdate, + ImportSetApiResponse, + ImportSetApiResponseError, + ServiceNowIncident, + GetApplicationInfoResponse, + SNProductsConfigValue, + ServiceFactory, +} from './types'; import * as i18n from './translations'; import { Logger } from '../../../../../../src/core/server'; -import { - ServiceNowPublicConfigurationType, - ServiceNowSecretConfigurationType, - ResponseError, -} from './types'; -import { request, getErrorMessage, addTimeZoneToDate, patch } from '../lib/axios_utils'; +import { ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType } from './types'; +import { request } from '../lib/axios_utils'; import { ActionsConfigurationUtilities } from '../../actions_config'; +import { createServiceError, getPushedDate, prepareIncident } from './utils'; -const API_VERSION = 'v2'; -const SYS_DICTIONARY = `api/now/${API_VERSION}/table/sys_dictionary`; +export const SYS_DICTIONARY_ENDPOINT = `api/now/table/sys_dictionary`; -export const createExternalService = ( - table: string, +export const createExternalService: ServiceFactory = ( { config, secrets }: ExternalServiceCredentials, logger: Logger, - configurationUtilities: ActionsConfigurationUtilities + configurationUtilities: ActionsConfigurationUtilities, + { table, importSetTable, useImportAPI, appScope }: SNProductsConfigValue ): ExternalService => { - const { apiUrl: url } = config as ServiceNowPublicConfigurationType; + const { apiUrl: url, isLegacy } = config as ServiceNowPublicConfigurationType; const { username, password } = secrets as ServiceNowSecretConfigurationType; if (!url || !username || !password) { @@ -36,13 +43,26 @@ export const createExternalService = ( } const urlWithoutTrailingSlash = url.endsWith('/') ? url.slice(0, -1) : url; - const incidentUrl = `${urlWithoutTrailingSlash}/api/now/${API_VERSION}/table/${table}`; - const fieldsUrl = `${urlWithoutTrailingSlash}/${SYS_DICTIONARY}?sysparm_query=name=task^ORname=${table}^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory`; - const choicesUrl = `${urlWithoutTrailingSlash}/api/now/${API_VERSION}/table/sys_choice`; + const importSetTableUrl = `${urlWithoutTrailingSlash}/api/now/import/${importSetTable}`; + const tableApiIncidentUrl = `${urlWithoutTrailingSlash}/api/now/v2/table/${table}`; + const fieldsUrl = `${urlWithoutTrailingSlash}/${SYS_DICTIONARY_ENDPOINT}?sysparm_query=name=task^ORname=${table}^internal_type=string&active=true&array=false&read_only=false&sysparm_fields=max_length,element,column_label,mandatory`; + const choicesUrl = `${urlWithoutTrailingSlash}/api/now/table/sys_choice`; + /** + * Need to be set the same at: + * x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts + */ + const getVersionUrl = () => `${urlWithoutTrailingSlash}/api/${appScope}/elastic_api/health`; + const axiosInstance = axios.create({ auth: { username, password }, }); + const useOldApi = !useImportAPI || isLegacy; + + const getCreateIncidentUrl = () => (useOldApi ? tableApiIncidentUrl : importSetTableUrl); + const getUpdateIncidentUrl = (incidentId: string) => + useOldApi ? `${tableApiIncidentUrl}/${incidentId}` : importSetTableUrl; + const getIncidentViewURL = (id: string) => { // Based on: https://docs.servicenow.com/bundle/orlando-platform-user-interface/page/use/navigation/reference/r_NavigatingByURLExamples.html return `${urlWithoutTrailingSlash}/nav_to.do?uri=${table}.do?sys_id=${id}`; @@ -57,7 +77,7 @@ export const createExternalService = ( }; const checkInstance = (res: AxiosResponse) => { - if (res.status === 200 && res.data.result == null) { + if (res.status >= 200 && res.status < 400 && res.data.result == null) { throw new Error( `There is an issue with your Service Now Instance. Please check ${ res.request?.connection?.servername ?? '' @@ -66,34 +86,70 @@ export const createExternalService = ( } }; - const createErrorMessage = (errorResponse: ResponseError): string => { - if (errorResponse == null) { - return ''; + const isImportSetApiResponseAnError = ( + data: ImportSetApiResponse['result'][0] + ): data is ImportSetApiResponseError['result'][0] => data.status === 'error'; + + const throwIfImportSetApiResponseIsAnError = (res: ImportSetApiResponse) => { + if (res.result.length === 0) { + throw new Error('Unexpected result'); } - const { error } = errorResponse; - return error != null ? `${error?.message}: ${error?.detail}` : ''; + const data = res.result[0]; + + // Create ResponseError message? + if (isImportSetApiResponseAnError(data)) { + throw new Error(data.error_message); + } }; - const getIncident = async (id: string) => { + /** + * Gets the Elastic SN Application information including the current version. + * It should not be used on legacy connectors. + */ + const getApplicationInformation = async (): Promise<GetApplicationInfoResponse> => { try { const res = await request({ axios: axiosInstance, - url: `${incidentUrl}/${id}`, + url: getVersionUrl(), logger, configurationUtilities, + method: 'get', }); + checkInstance(res); + return { ...res.data.result }; } catch (error) { - throw new Error( - getErrorMessage( - i18n.SERVICENOW, - `Unable to get incident with id ${id}. Error: ${ - error.message - } Reason: ${createErrorMessage(error.response?.data)}` - ) - ); + throw createServiceError(error, 'Unable to get application version'); + } + }; + + const logApplicationInfo = (scope: string, version: string) => + logger.debug(`Create incident: Application scope: ${scope}: Application version${version}`); + + const checkIfApplicationIsInstalled = async () => { + if (!useOldApi) { + const { version, scope } = await getApplicationInformation(); + logApplicationInfo(scope, version); + } + }; + + const getIncident = async (id: string): Promise<ServiceNowIncident> => { + try { + const res = await request({ + axios: axiosInstance, + url: `${tableApiIncidentUrl}/${id}`, + logger, + configurationUtilities, + method: 'get', + }); + + checkInstance(res); + + return { ...res.data.result }; + } catch (error) { + throw createServiceError(error, `Unable to get incident with id ${id}`); } }; @@ -101,7 +157,7 @@ export const createExternalService = ( try { const res = await request({ axios: axiosInstance, - url: incidentUrl, + url: tableApiIncidentUrl, logger, params, configurationUtilities, @@ -109,71 +165,80 @@ export const createExternalService = ( checkInstance(res); return res.data.result.length > 0 ? { ...res.data.result } : undefined; } catch (error) { - throw new Error( - getErrorMessage( - i18n.SERVICENOW, - `Unable to find incidents by query. Error: ${error.message} Reason: ${createErrorMessage( - error.response?.data - )}` - ) - ); + throw createServiceError(error, 'Unable to find incidents by query'); } }; - const createIncident = async ({ incident }: ExternalServiceParams) => { + const getUrl = () => urlWithoutTrailingSlash; + + const createIncident = async ({ incident }: ExternalServiceParamsCreate) => { try { + await checkIfApplicationIsInstalled(); + const res = await request({ axios: axiosInstance, - url: `${incidentUrl}`, + url: getCreateIncidentUrl(), logger, method: 'post', - data: { ...(incident as Record<string, unknown>) }, + data: prepareIncident(useOldApi, incident), configurationUtilities, }); + checkInstance(res); + + if (!useOldApi) { + throwIfImportSetApiResponseIsAnError(res.data); + } + + const incidentId = useOldApi ? res.data.result.sys_id : res.data.result[0].sys_id; + const insertedIncident = await getIncident(incidentId); + return { - title: res.data.result.number, - id: res.data.result.sys_id, - pushedDate: new Date(addTimeZoneToDate(res.data.result.sys_created_on)).toISOString(), - url: getIncidentViewURL(res.data.result.sys_id), + title: insertedIncident.number, + id: insertedIncident.sys_id, + pushedDate: getPushedDate(insertedIncident.sys_created_on), + url: getIncidentViewURL(insertedIncident.sys_id), }; } catch (error) { - throw new Error( - getErrorMessage( - i18n.SERVICENOW, - `Unable to create incident. Error: ${error.message} Reason: ${createErrorMessage( - error.response?.data - )}` - ) - ); + throw createServiceError(error, 'Unable to create incident'); } }; - const updateIncident = async ({ incidentId, incident }: ExternalServiceParams) => { + const updateIncident = async ({ incidentId, incident }: ExternalServiceParamsUpdate) => { try { - const res = await patch({ + await checkIfApplicationIsInstalled(); + + const res = await request({ axios: axiosInstance, - url: `${incidentUrl}/${incidentId}`, + url: getUpdateIncidentUrl(incidentId), + // Import Set API supports only POST. + method: useOldApi ? 'patch' : 'post', logger, - data: { ...(incident as Record<string, unknown>) }, + data: { + ...prepareIncident(useOldApi, incident), + // elastic_incident_id is used to update the incident when using the Import Set API. + ...(useOldApi ? {} : { elastic_incident_id: incidentId }), + }, configurationUtilities, }); + checkInstance(res); + + if (!useOldApi) { + throwIfImportSetApiResponseIsAnError(res.data); + } + + const id = useOldApi ? res.data.result.sys_id : res.data.result[0].sys_id; + const updatedIncident = await getIncident(id); + return { - title: res.data.result.number, - id: res.data.result.sys_id, - pushedDate: new Date(addTimeZoneToDate(res.data.result.sys_updated_on)).toISOString(), - url: getIncidentViewURL(res.data.result.sys_id), + title: updatedIncident.number, + id: updatedIncident.sys_id, + pushedDate: getPushedDate(updatedIncident.sys_updated_on), + url: getIncidentViewURL(updatedIncident.sys_id), }; } catch (error) { - throw new Error( - getErrorMessage( - i18n.SERVICENOW, - `Unable to update incident with id ${incidentId}. Error: ${ - error.message - } Reason: ${createErrorMessage(error.response?.data)}` - ) - ); + throw createServiceError(error, `Unable to update incident with id ${incidentId}`); } }; @@ -185,17 +250,12 @@ export const createExternalService = ( logger, configurationUtilities, }); + checkInstance(res); + return res.data.result.length > 0 ? res.data.result : []; } catch (error) { - throw new Error( - getErrorMessage( - i18n.SERVICENOW, - `Unable to get fields. Error: ${error.message} Reason: ${createErrorMessage( - error.response?.data - )}` - ) - ); + throw createServiceError(error, 'Unable to get fields'); } }; @@ -210,14 +270,7 @@ export const createExternalService = ( checkInstance(res); return res.data.result; } catch (error) { - throw new Error( - getErrorMessage( - i18n.SERVICENOW, - `Unable to get choices. Error: ${error.message} Reason: ${createErrorMessage( - error.response?.data - )}` - ) - ); + throw createServiceError(error, 'Unable to get choices'); } }; @@ -228,5 +281,9 @@ export const createExternalService = ( getIncident, updateIncident, getChoices, + getUrl, + checkInstance, + getApplicationInformation, + checkIfApplicationIsInstalled, }; }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service_sir.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service_sir.test.ts new file mode 100644 index 0000000000000..0fc94b6287abd --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service_sir.test.ts @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import axios from 'axios'; + +import { createExternalServiceSIR } from './service_sir'; +import * as utils from '../lib/axios_utils'; +import { ExternalServiceSIR } from './types'; +import { Logger } from '../../../../../../src/core/server'; +import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; +import { actionsConfigMock } from '../../actions_config.mock'; +import { observables } from './mocks'; +import { snExternalServiceConfig } from './config'; + +const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>; + +jest.mock('axios'); +jest.mock('../lib/axios_utils', () => { + const originalUtils = jest.requireActual('../lib/axios_utils'); + return { + ...originalUtils, + request: jest.fn(), + patch: jest.fn(), + }; +}); + +axios.create = jest.fn(() => axios); +const requestMock = utils.request as jest.Mock; +const configurationUtilities = actionsConfigMock.create(); + +const mockApplicationVersion = () => + requestMock.mockImplementationOnce(() => ({ + data: { + result: { name: 'Elastic', scope: 'x_elas2_sir_int', version: '1.0.0' }, + }, + })); + +const getAddObservablesResponse = () => [ + { + value: '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9', + observable_sys_id: '1', + }, + { + value: '127.0.0.1', + observable_sys_id: '2', + }, + { + value: 'https://example.com', + observable_sys_id: '3', + }, +]; + +const mockAddObservablesResponse = (single: boolean) => { + const res = getAddObservablesResponse(); + requestMock.mockImplementation(() => ({ + data: { + result: single ? res[0] : res, + }, + })); +}; + +const expectAddObservables = (single: boolean) => { + expect(requestMock).toHaveBeenNthCalledWith(1, { + axios, + logger, + configurationUtilities, + url: 'https://example.com/api/x_elas2_sir_int/elastic_api/health', + method: 'get', + }); + + const url = single + ? 'https://example.com/api/x_elas2_sir_int/elastic_api/incident/incident-1/observables' + : 'https://example.com/api/x_elas2_sir_int/elastic_api/incident/incident-1/observables/bulk'; + + const data = single ? observables[0] : observables; + + expect(requestMock).toHaveBeenNthCalledWith(2, { + axios, + logger, + configurationUtilities, + url, + method: 'post', + data, + }); +}; + +describe('ServiceNow SIR service', () => { + let service: ExternalServiceSIR; + + beforeEach(() => { + service = createExternalServiceSIR( + { + config: { apiUrl: 'https://example.com/' }, + secrets: { username: 'admin', password: 'admin' }, + }, + logger, + configurationUtilities, + snExternalServiceConfig['.servicenow-sir'] + ) as ExternalServiceSIR; + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('bulkAddObservableToIncident', () => { + test('it adds multiple observables correctly', async () => { + mockApplicationVersion(); + mockAddObservablesResponse(false); + + const res = await service.bulkAddObservableToIncident(observables, 'incident-1'); + expect(res).toEqual(getAddObservablesResponse()); + expectAddObservables(false); + }); + + test('it adds a single observable correctly', async () => { + mockApplicationVersion(); + mockAddObservablesResponse(true); + + const res = await service.addObservableToIncident(observables[0], 'incident-1'); + expect(res).toEqual(getAddObservablesResponse()[0]); + expectAddObservables(true); + }); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service_sir.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service_sir.ts new file mode 100644 index 0000000000000..fc8d8cc555bc8 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service_sir.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import axios from 'axios'; + +import { + ExternalServiceCredentials, + SNProductsConfigValue, + Observable, + ExternalServiceSIR, + ObservableResponse, + ServiceFactory, +} from './types'; + +import { Logger } from '../../../../../../src/core/server'; +import { ServiceNowSecretConfigurationType } from './types'; +import { request } from '../lib/axios_utils'; +import { ActionsConfigurationUtilities } from '../../actions_config'; +import { createExternalService } from './service'; +import { createServiceError } from './utils'; + +const getAddObservableToIncidentURL = (url: string, incidentID: string) => + `${url}/api/x_elas2_sir_int/elastic_api/incident/${incidentID}/observables`; + +const getBulkAddObservableToIncidentURL = (url: string, incidentID: string) => + `${url}/api/x_elas2_sir_int/elastic_api/incident/${incidentID}/observables/bulk`; + +export const createExternalServiceSIR: ServiceFactory = ( + credentials: ExternalServiceCredentials, + logger: Logger, + configurationUtilities: ActionsConfigurationUtilities, + serviceConfig: SNProductsConfigValue +): ExternalServiceSIR => { + const snService = createExternalService( + credentials, + logger, + configurationUtilities, + serviceConfig + ); + + const { username, password } = credentials.secrets as ServiceNowSecretConfigurationType; + const axiosInstance = axios.create({ + auth: { username, password }, + }); + + const _addObservable = async (data: Observable | Observable[], url: string) => { + snService.checkIfApplicationIsInstalled(); + + const res = await request({ + axios: axiosInstance, + url, + logger, + method: 'post', + data, + configurationUtilities, + }); + + snService.checkInstance(res); + return res.data.result; + }; + + const addObservableToIncident = async ( + observable: Observable, + incidentID: string + ): Promise<ObservableResponse> => { + try { + return await _addObservable( + observable, + getAddObservableToIncidentURL(snService.getUrl(), incidentID) + ); + } catch (error) { + throw createServiceError( + error, + `Unable to add observable to security incident with id ${incidentID}` + ); + } + }; + + const bulkAddObservableToIncident = async ( + observables: Observable[], + incidentID: string + ): Promise<ObservableResponse[]> => { + try { + return await _addObservable( + observables, + getBulkAddObservableToIncidentURL(snService.getUrl(), incidentID) + ); + } catch (error) { + throw createServiceError( + error, + `Unable to add observables to security incident with id ${incidentID}` + ); + } + }; + return { + ...snService, + addObservableToIncident, + bulkAddObservableToIncident, + }; +}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts index 50631cf289a73..ecca1e55e0fec 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts @@ -7,6 +7,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { AxiosError, AxiosResponse } from 'axios'; import { TypeOf } from '@kbn/config-schema'; import { ExecutorParamsSchemaITSM, @@ -78,15 +79,29 @@ export interface PushToServiceResponse extends ExternalServiceIncidentResponse { comments?: ExternalServiceCommentResponse[]; } -export type ExternalServiceParams = Record<string, unknown>; +export type Incident = ServiceNowITSMIncident | ServiceNowSIRIncident; +export type PartialIncident = Partial<Incident>; + +export interface ExternalServiceParamsCreate { + incident: Incident & Record<string, unknown>; +} + +export interface ExternalServiceParamsUpdate { + incidentId: string; + incident: PartialIncident & Record<string, unknown>; +} export interface ExternalService { getChoices: (fields: string[]) => Promise<GetChoicesResponse>; - getIncident: (id: string) => Promise<ExternalServiceParams | undefined>; + getIncident: (id: string) => Promise<ServiceNowIncident>; getFields: () => Promise<GetCommonFieldsResponse>; - createIncident: (params: ExternalServiceParams) => Promise<ExternalServiceIncidentResponse>; - updateIncident: (params: ExternalServiceParams) => Promise<ExternalServiceIncidentResponse>; - findIncidents: (params?: Record<string, string>) => Promise<ExternalServiceParams[] | undefined>; + createIncident: (params: ExternalServiceParamsCreate) => Promise<ExternalServiceIncidentResponse>; + updateIncident: (params: ExternalServiceParamsUpdate) => Promise<ExternalServiceIncidentResponse>; + findIncidents: (params?: Record<string, string>) => Promise<ServiceNowIncident>; + getUrl: () => string; + checkInstance: (res: AxiosResponse) => void; + getApplicationInformation: () => Promise<GetApplicationInfoResponse>; + checkIfApplicationIsInstalled: () => Promise<void>; } export type PushToServiceApiParams = ExecutorSubActionPushParams; @@ -115,10 +130,9 @@ export type ServiceNowSIRIncident = Omit< 'externalId' >; -export type Incident = ServiceNowITSMIncident | ServiceNowSIRIncident; - export interface PushToServiceApiHandlerArgs extends ExternalServiceApiHandlerArgs { params: PushToServiceApiParams; + config: Record<string, unknown>; secrets: Record<string, unknown>; logger: Logger; commentFieldKey: string; @@ -158,12 +172,20 @@ export interface GetChoicesHandlerArgs { params: ExecutorSubActionGetChoicesParams; } -export interface ExternalServiceApi { +export interface ServiceNowIncident { + sys_id: string; + number: string; + sys_created_on: string; + sys_updated_on: string; + [x: string]: unknown; +} + +export interface ExternalServiceAPI { getChoices: (args: GetChoicesHandlerArgs) => Promise<GetChoicesResponse>; getFields: (args: GetCommonFieldsHandlerArgs) => Promise<GetCommonFieldsResponse>; handshake: (args: HandshakeApiHandlerArgs) => Promise<void>; pushToService: (args: PushToServiceApiHandlerArgs) => Promise<PushToServiceResponse>; - getIncident: (args: GetIncidentApiHandlerArgs) => Promise<void>; + getIncident: (args: GetIncidentApiHandlerArgs) => Promise<ServiceNowIncident>; } export interface ExternalServiceCommentResponse { @@ -173,10 +195,90 @@ export interface ExternalServiceCommentResponse { } type TypeNullOrUndefined<T> = T | null | undefined; -export interface ResponseError { + +export interface ServiceNowError { error: TypeNullOrUndefined<{ message: TypeNullOrUndefined<string>; detail: TypeNullOrUndefined<string>; }>; status: TypeNullOrUndefined<string>; } + +export type ResponseError = AxiosError<ServiceNowError>; + +export interface ImportSetApiResponseSuccess { + import_set: string; + staging_table: string; + result: Array<{ + display_name: string; + display_value: string; + record_link: string; + status: string; + sys_id: string; + table: string; + transform_map: string; + }>; +} + +export interface ImportSetApiResponseError { + import_set: string; + staging_table: string; + result: Array<{ + error_message: string; + status_message: string; + status: string; + transform_map: string; + }>; +} + +export type ImportSetApiResponse = ImportSetApiResponseSuccess | ImportSetApiResponseError; +export interface GetApplicationInfoResponse { + id: string; + name: string; + scope: string; + version: string; +} + +export interface SNProductsConfigValue { + table: string; + appScope: string; + useImportAPI: boolean; + importSetTable: string; + commentFieldKey: string; +} + +export type SNProductsConfig = Record<string, SNProductsConfigValue>; + +export enum ObservableTypes { + ip4 = 'ipv4-addr', + url = 'URL', + sha256 = 'SHA256', +} + +export interface Observable { + value: string; + type: ObservableTypes; +} + +export interface ObservableResponse { + value: string; + observable_sys_id: ObservableTypes; +} + +export interface ExternalServiceSIR extends ExternalService { + addObservableToIncident: ( + observable: Observable, + incidentID: string + ) => Promise<ObservableResponse>; + bulkAddObservableToIncident: ( + observables: Observable[], + incidentID: string + ) => Promise<ObservableResponse[]>; +} + +export type ServiceFactory = ( + credentials: ExternalServiceCredentials, + logger: Logger, + configurationUtilities: ActionsConfigurationUtilities, + serviceConfig: SNProductsConfigValue +) => ExternalServiceSIR | ExternalService; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/utils.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/utils.test.ts new file mode 100644 index 0000000000000..87f27da6d213f --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/utils.test.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AxiosError } from 'axios'; +import { prepareIncident, createServiceError, getPushedDate } from './utils'; + +/** + * The purpose of this test is to + * prevent developers from accidentally + * change important configuration values + * such as the scope or the import set table + * of our ServiceNow application + */ + +describe('utils', () => { + describe('prepareIncident', () => { + test('it prepares the incident correctly when useOldApi=false', async () => { + const incident = { short_description: 'title', description: 'desc' }; + const newIncident = prepareIncident(false, incident); + expect(newIncident).toEqual({ u_short_description: 'title', u_description: 'desc' }); + }); + + test('it prepares the incident correctly when useOldApi=true', async () => { + const incident = { short_description: 'title', description: 'desc' }; + const newIncident = prepareIncident(true, incident); + expect(newIncident).toEqual(incident); + }); + }); + + describe('createServiceError', () => { + test('it creates an error when the response is null', async () => { + const error = new Error('An error occurred'); + // @ts-expect-error + expect(createServiceError(error, 'Unable to do action').message).toBe( + '[Action][ServiceNow]: Unable to do action. Error: An error occurred Reason: unknown: errorResponse was null' + ); + }); + + test('it creates an error with response correctly', async () => { + const axiosError = { + message: 'An error occurred', + response: { data: { error: { message: 'Denied', detail: 'no access' } } }, + } as AxiosError; + + expect(createServiceError(axiosError, 'Unable to do action').message).toBe( + '[Action][ServiceNow]: Unable to do action. Error: An error occurred Reason: Denied: no access' + ); + }); + + test('it creates an error correctly when the ServiceNow error is null', async () => { + const axiosError = { + message: 'An error occurred', + response: { data: { error: null } }, + } as AxiosError; + + expect(createServiceError(axiosError, 'Unable to do action').message).toBe( + '[Action][ServiceNow]: Unable to do action. Error: An error occurred Reason: unknown: no error in error response' + ); + }); + }); + + describe('getPushedDate', () => { + beforeAll(() => { + jest.useFakeTimers('modern'); + jest.setSystemTime(new Date('2021-10-04 11:15:06 GMT')); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + test('it formats the date correctly if timestamp is provided', async () => { + expect(getPushedDate('2021-10-04 11:15:06')).toBe('2021-10-04T11:15:06.000Z'); + }); + + test('it formats the date correctly if timestamp is not provided', async () => { + expect(getPushedDate()).toBe('2021-10-04T11:15:06.000Z'); + }); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/utils.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/utils.ts new file mode 100644 index 0000000000000..5b7ca99ffc709 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/utils.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Incident, PartialIncident, ResponseError, ServiceNowError } from './types'; +import { FIELD_PREFIX } from './config'; +import { addTimeZoneToDate, getErrorMessage } from '../lib/axios_utils'; +import * as i18n from './translations'; + +export const prepareIncident = (useOldApi: boolean, incident: PartialIncident): PartialIncident => + useOldApi + ? incident + : Object.entries(incident).reduce( + (acc, [key, value]) => ({ ...acc, [`${FIELD_PREFIX}${key}`]: value }), + {} as Incident + ); + +const createErrorMessage = (errorResponse?: ServiceNowError): string => { + if (errorResponse == null) { + return 'unknown: errorResponse was null'; + } + + const { error } = errorResponse; + return error != null + ? `${error?.message}: ${error?.detail}` + : 'unknown: no error in error response'; +}; + +export const createServiceError = (error: ResponseError, message: string) => + new Error( + getErrorMessage( + i18n.SERVICENOW, + `${message}. Error: ${error.message} Reason: ${createErrorMessage(error.response?.data)}` + ) + ); + +export const getPushedDate = (timestamp?: string) => { + if (timestamp != null) { + return new Date(addTimeZoneToDate(timestamp)).toISOString(); + } + + return new Date().toISOString(); +}; diff --git a/x-pack/plugins/xpack_legacy/server/index.ts b/x-pack/plugins/actions/server/constants/connectors.ts similarity index 52% rename from x-pack/plugins/xpack_legacy/server/index.ts rename to x-pack/plugins/actions/server/constants/connectors.ts index ee51afcca429f..f20d499716cf0 100644 --- a/x-pack/plugins/xpack_legacy/server/index.ts +++ b/x-pack/plugins/actions/server/constants/connectors.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { PluginInitializerContext } from '../../../../src/core/server'; -import { XpackLegacyPlugin } from './plugin'; +// TODO: Remove when Elastic for ITSM is published. +export const ENABLE_NEW_SN_ITSM_CONNECTOR = true; -export const plugin = (initializerContext: PluginInitializerContext) => - new XpackLegacyPlugin(initializerContext); +// TODO: Remove when Elastic for Security Operations is published. +export const ENABLE_NEW_SN_SIR_CONNECTOR = true; diff --git a/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts index c094109a43d97..9f8e62c77e3a7 100644 --- a/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts @@ -165,6 +165,47 @@ describe('successful migrations', () => { }); expect(migratedAction).toEqual(action); }); + + test('set isLegacy config property for .servicenow', () => { + const migration716 = getActionsMigrations(encryptedSavedObjectsSetup)['7.16.0']; + const action = getMockDataForServiceNow(); + const migratedAction = migration716(action, context); + + expect(migratedAction).toEqual({ + ...action, + attributes: { + ...action.attributes, + config: { + apiUrl: 'https://example.com', + isLegacy: true, + }, + }, + }); + }); + + test('set isLegacy config property for .servicenow-sir', () => { + const migration716 = getActionsMigrations(encryptedSavedObjectsSetup)['7.16.0']; + const action = getMockDataForServiceNow({ actionTypeId: '.servicenow-sir' }); + const migratedAction = migration716(action, context); + + expect(migratedAction).toEqual({ + ...action, + attributes: { + ...action.attributes, + config: { + apiUrl: 'https://example.com', + isLegacy: true, + }, + }, + }); + }); + + test('it does not set isLegacy config for other connectors', () => { + const migration716 = getActionsMigrations(encryptedSavedObjectsSetup)['7.16.0']; + const action = getMockData(); + const migratedAction = migration716(action, context); + expect(migratedAction).toEqual(action); + }); }); describe('8.0.0', () => { @@ -306,3 +347,19 @@ function getMockData( type: 'action', }; } + +function getMockDataForServiceNow( + overwrites: Record<string, unknown> = {} +): SavedObjectUnsanitizedDoc<Omit<RawAction, 'isMissingSecrets'>> { + return { + attributes: { + name: 'abc', + actionTypeId: '.servicenow', + config: { apiUrl: 'https://example.com' }, + secrets: { user: 'test', password: '123' }, + ...overwrites, + }, + id: uuid.v4(), + type: 'action', + }; +} diff --git a/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts b/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts index e75f3eb41f2df..688839eb89858 100644 --- a/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts @@ -59,13 +59,16 @@ export function getActionsMigrations( const migrationActionsFourteen = createEsoMigration( encryptedSavedObjects, (doc): doc is SavedObjectUnsanitizedDoc<RawAction> => true, - pipeMigrations(addisMissingSecretsField) + pipeMigrations(addIsMissingSecretsField) ); - const migrationEmailActionsSixteen = createEsoMigration( + const migrationActionsSixteen = createEsoMigration( encryptedSavedObjects, - (doc): doc is SavedObjectUnsanitizedDoc<RawAction> => doc.attributes.actionTypeId === '.email', - pipeMigrations(setServiceConfigIfNotSet) + (doc): doc is SavedObjectUnsanitizedDoc<RawAction> => + doc.attributes.actionTypeId === '.servicenow' || + doc.attributes.actionTypeId === '.servicenow-sir' || + doc.attributes.actionTypeId === '.email', + pipeMigrations(markOldServiceNowITSMConnectorAsLegacy, setServiceConfigIfNotSet) ); const migrationActions800 = createEsoMigration( @@ -79,7 +82,7 @@ export function getActionsMigrations( '7.10.0': executeMigrationWithErrorHandling(migrationActionsTen, '7.10.0'), '7.11.0': executeMigrationWithErrorHandling(migrationActionsEleven, '7.11.0'), '7.14.0': executeMigrationWithErrorHandling(migrationActionsFourteen, '7.14.0'), - '7.16.0': executeMigrationWithErrorHandling(migrationEmailActionsSixteen, '7.16.0'), + '7.16.0': executeMigrationWithErrorHandling(migrationActionsSixteen, '7.16.0'), '8.0.0': executeMigrationWithErrorHandling(migrationActions800, '8.0.0'), }; } @@ -182,7 +185,7 @@ const setServiceConfigIfNotSet = ( }; }; -const addisMissingSecretsField = ( +const addIsMissingSecretsField = ( doc: SavedObjectUnsanitizedDoc<RawAction> ): SavedObjectUnsanitizedDoc<RawAction> => { return { @@ -194,6 +197,28 @@ const addisMissingSecretsField = ( }; }; +const markOldServiceNowITSMConnectorAsLegacy = ( + doc: SavedObjectUnsanitizedDoc<RawAction> +): SavedObjectUnsanitizedDoc<RawAction> => { + if ( + doc.attributes.actionTypeId !== '.servicenow' && + doc.attributes.actionTypeId !== '.servicenow-sir' + ) { + return doc; + } + + return { + ...doc, + attributes: { + ...doc.attributes, + config: { + ...doc.attributes.config, + isLegacy: true, + }, + }, + }; +}; + function pipeMigrations(...migrations: ActionMigration[]): ActionMigration { return (doc: SavedObjectUnsanitizedDoc<RawAction>) => migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc); diff --git a/x-pack/plugins/actions/server/saved_objects/index.ts b/x-pack/plugins/actions/server/saved_objects/index.ts index 14b425d20af13..c3598df809bcf 100644 --- a/x-pack/plugins/actions/server/saved_objects/index.ts +++ b/x-pack/plugins/actions/server/saved_objects/index.ts @@ -40,6 +40,7 @@ export function setupSavedObjects( mappings: mappings.action as SavedObjectsTypeMappingDefinition, migrations: getActionsMigrations(encryptedSavedObjects), management: { + displayName: 'connector', defaultSearchField: 'name', importableAndExportable: true, getTitle(savedObject: SavedObject<RawAction>) { diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts index 4049d8fc3b594..0e6b7fff04451 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts @@ -116,7 +116,7 @@ Object { test('getInUseTotalCount', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockReturnValueOnce( // @ts-expect-error not full search response elasticsearchClientMock.createSuccessTransportRequestPromise({ aggregations: { @@ -134,28 +134,35 @@ Object { }, }) ); - const actionsBulkGet = jest.fn(); - actionsBulkGet.mockReturnValue({ - saved_objects: [ - { - id: '1', - attributes: { - actionTypeId: '.server-log', - }, - }, - { - id: '123', - attributes: { - actionTypeId: '.slack', - }, - }, - ], - }); - const telemetry = await getInUseTotalCount(mockEsClient, actionsBulkGet, 'test'); - expect(mockEsClient.search).toHaveBeenCalledTimes(1); - expect(actionsBulkGet).toHaveBeenCalledTimes(1); + mockEsClient.search.mockReturnValueOnce( + // @ts-expect-error not full search response + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [ + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', + }, + }, + }, + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', + }, + }, + }, + ], + }, + }) + ); + const telemetry = await getInUseTotalCount(mockEsClient, 'test'); + expect(mockEsClient.search).toHaveBeenCalledTimes(2); expect(telemetry).toMatchInlineSnapshot(` Object { "countByAlertHistoryConnectorType": 0, @@ -170,7 +177,7 @@ Object { test('getInUseTotalCount should count preconfigured alert history connector usage', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockReturnValueOnce( // @ts-expect-error not full search response elasticsearchClientMock.createSuccessTransportRequestPromise({ aggregations: { @@ -202,28 +209,34 @@ Object { }, }) ); - const actionsBulkGet = jest.fn(); - actionsBulkGet.mockReturnValue({ - saved_objects: [ - { - id: '1', - attributes: { - actionTypeId: '.server-log', - }, - }, - { - id: '123', - attributes: { - actionTypeId: '.slack', - }, + mockEsClient.search.mockReturnValueOnce( + // @ts-expect-error not full search response + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [ + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', + }, + }, + }, + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', + }, + }, + }, + ], }, - ], - }); - const telemetry = await getInUseTotalCount(mockEsClient, actionsBulkGet, 'test'); - - expect(mockEsClient.search).toHaveBeenCalledTimes(1); - expect(actionsBulkGet).toHaveBeenCalledTimes(1); + }) + ); + const telemetry = await getInUseTotalCount(mockEsClient, 'test'); + expect(mockEsClient.search).toHaveBeenCalledTimes(2); expect(telemetry).toMatchInlineSnapshot(` Object { "countByAlertHistoryConnectorType": 1, @@ -359,7 +372,7 @@ Object { test('getInUseTotalCount() accounts for preconfigured connectors', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockReturnValueOnce( // @ts-expect-error not full search response elasticsearchClientMock.createSuccessTransportRequestPromise({ aggregations: { @@ -399,34 +412,42 @@ Object { }, }) ); - const actionsBulkGet = jest.fn(); - actionsBulkGet.mockReturnValue({ - saved_objects: [ - { - id: '1', - attributes: { - actionTypeId: '.server-log', - }, - }, - { - id: '123', - attributes: { - actionTypeId: '.slack', - }, - }, - { - id: '456', - attributes: { - actionTypeId: '.email', - }, + mockEsClient.search.mockReturnValueOnce( + // @ts-expect-error not full search response + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [ + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', + }, + }, + }, + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', + }, + }, + }, + { + _source: { + action: { + id: '3', + actionTypeId: '.email', + }, + }, + }, + ], }, - ], - }); - const telemetry = await getInUseTotalCount(mockEsClient, actionsBulkGet, 'test'); - - expect(mockEsClient.search).toHaveBeenCalledTimes(1); - expect(actionsBulkGet).toHaveBeenCalledTimes(1); + }) + ); + const telemetry = await getInUseTotalCount(mockEsClient, 'test'); + expect(mockEsClient.search).toHaveBeenCalledTimes(2); expect(telemetry).toMatchInlineSnapshot(` Object { "countByAlertHistoryConnectorType": 1, diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.ts index 544d6a411ccdc..4a3d0c70e535a 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.ts @@ -5,12 +5,7 @@ * 2.0. */ -import { - ElasticsearchClient, - SavedObjectsBaseOptions, - SavedObjectsBulkGetObject, - SavedObjectsBulkResponse, -} from 'kibana/server'; +import { ElasticsearchClient } from 'kibana/server'; import { AlertHistoryEsIndexConnectorId } from '../../common'; import { ActionResult, PreConfiguredAction } from '../types'; @@ -86,10 +81,6 @@ export async function getTotalCount( export async function getInUseTotalCount( esClient: ElasticsearchClient, - actionsBulkGet: ( - objects?: SavedObjectsBulkGetObject[] | undefined, - options?: SavedObjectsBaseOptions | undefined - ) => Promise<SavedObjectsBulkResponse<ActionResult<Record<string, unknown>>>>, kibanaIndex: string ): Promise<{ countTotal: number; @@ -259,15 +250,34 @@ export async function getInUseTotalCount( const preconfiguredActionsAggs = // @ts-expect-error aggegation type is not specified actionResults.aggregations.preconfigured_actions?.preconfiguredActionRefIds.value; - const bulkFilter = Object.entries(aggs.connectorIds).map(([key]) => ({ - id: key, - type: 'action', - fields: ['id', 'actionTypeId'], - })); - const actions = await actionsBulkGet(bulkFilter); - const countByActionTypeId = actions.saved_objects.reduce( + const { + body: { hits: actions }, + } = await esClient.search<{ + action: ActionResult; + }>({ + index: kibanaIndex, + _source_includes: ['action'], + body: { + query: { + bool: { + must: [ + { + term: { type: 'action' }, + }, + { + terms: { + _id: Object.entries(aggs.connectorIds).map(([key]) => `action:${key}`), + }, + }, + ], + }, + }, + }, + }); + const countByActionTypeId = actions.hits.reduce( (actionTypeCount: Record<string, number>, action) => { - const alertTypeId = replaceFirstAndLastDotSymbols(action.attributes.actionTypeId); + const actionSource = action._source!; + const alertTypeId = replaceFirstAndLastDotSymbols(actionSource.action.actionTypeId); const currentCount = actionTypeCount[alertTypeId] !== undefined ? actionTypeCount[alertTypeId] : 0; actionTypeCount[alertTypeId] = currentCount + 1; diff --git a/x-pack/plugins/actions/server/usage/task.ts b/x-pack/plugins/actions/server/usage/task.ts index f37f830697eb5..7cbfb87dedda6 100644 --- a/x-pack/plugins/actions/server/usage/task.ts +++ b/x-pack/plugins/actions/server/usage/task.ts @@ -5,19 +5,14 @@ * 2.0. */ -import { - Logger, - CoreSetup, - SavedObjectsBulkGetObject, - SavedObjectsBaseOptions, -} from 'kibana/server'; +import { Logger, CoreSetup } from 'kibana/server'; import moment from 'moment'; import { RunContext, TaskManagerSetupContract, TaskManagerStartContract, } from '../../../task_manager/server'; -import { ActionResult, PreConfiguredAction } from '../types'; +import { PreConfiguredAction } from '../types'; import { getTotalCount, getInUseTotalCount } from './actions_telemetry'; export const TELEMETRY_TASK_TYPE = 'actions_telemetry'; @@ -83,22 +78,12 @@ export function telemetryTaskRunner( }, ]) => client.asInternalUser ); - const actionsBulkGet = ( - objects?: SavedObjectsBulkGetObject[], - options?: SavedObjectsBaseOptions - ) => { - return core - .getStartServices() - .then(([{ savedObjects }]) => - savedObjects.createInternalRepository(['action']).bulkGet<ActionResult>(objects, options) - ); - }; return { async run() { const esClient = await getEsClient(); return Promise.all([ getTotalCount(esClient, kibanaIndex, preconfiguredActions), - getInUseTotalCount(esClient, actionsBulkGet, kibanaIndex), + getInUseTotalCount(esClient, kibanaIndex), ]) .then(([totalAggegations, totalInUse]) => { return { diff --git a/x-pack/plugins/alerting/server/saved_objects/index.ts b/x-pack/plugins/alerting/server/saved_objects/index.ts index f1afba147a2f7..eb561b3c285f8 100644 --- a/x-pack/plugins/alerting/server/saved_objects/index.ts +++ b/x-pack/plugins/alerting/server/saved_objects/index.ts @@ -58,6 +58,7 @@ export function setupSavedObjects( migrations: getMigrations(encryptedSavedObjects, isPreconfigured), mappings: mappings.alert as SavedObjectsTypeMappingDefinition, management: { + displayName: 'rule', importableAndExportable: true, getTitle(ruleSavedObject: SavedObject<RawAlert>) { return `Rule: [${ruleSavedObject.attributes.name}]`; diff --git a/x-pack/plugins/apm/dev_docs/linting.md b/x-pack/plugins/apm/dev_docs/linting.md index a4fd3094f121c..7db7053e59061 100644 --- a/x-pack/plugins/apm/dev_docs/linting.md +++ b/x-pack/plugins/apm/dev_docs/linting.md @@ -1,6 +1,6 @@ -## Linting +# Linting -_Note: Run the following commands from the root of Kibana._ +_Note: Run the commands from the root of Kibana._ ### Typescript @@ -19,4 +19,3 @@ yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write ``` node scripts/eslint.js x-pack/legacy/plugins/apm ``` -diff --git a/x-pack/plugins/apm/dev_docs/feature_flags.md b/x-pack/plugins/apm/dev_docs/feature_flags.md diff --git a/x-pack/plugins/apm/dev_docs/testing.md b/x-pack/plugins/apm/dev_docs/testing.md index 4d0edc27fe644..ba48e7e229e27 100644 --- a/x-pack/plugins/apm/dev_docs/testing.md +++ b/x-pack/plugins/apm/dev_docs/testing.md @@ -64,3 +64,13 @@ node scripts/functional_test_runner --config x-pack/test/functional/config.js -- APM tests are located in `x-pack/test/functional/apps/apm`. For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) diff --git a/x-pack/plugins/apm/scripts/test/README.md b/x-pack/plugins/apm/scripts/test/README.md + + +## Storybook + +### Start +``` +yarn storybook apm +``` + +All files with a .stories.tsx extension will be loaded. You can access the development environment at http://localhost:9001. diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts index 1e954d9982295..56704d63a42f1 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -/* eslint-disable @typescript-eslint/naming-convention */ const apmIndicesSaveURL = '/internal/apm/settings/apm-indices/save'; @@ -20,12 +19,12 @@ describe('No data screen', () => { url: apmIndicesSaveURL, method: 'POST', body: { - 'apm_oss.sourcemapIndices': 'foo-*', - 'apm_oss.errorIndices': 'foo-*', - 'apm_oss.onboardingIndices': 'foo-*', - 'apm_oss.spanIndices': 'foo-*', - 'apm_oss.transactionIndices': 'foo-*', - 'apm_oss.metricsIndices': 'foo-*', + sourcemap: 'foo-*', + error: 'foo-*', + onboarding: 'foo-*', + span: 'foo-*', + transaction: 'foo-*', + metric: 'foo-*', }, headers: { 'kbn-xsrf': true, @@ -50,12 +49,12 @@ describe('No data screen', () => { url: apmIndicesSaveURL, method: 'POST', body: { - 'apm_oss.sourcemapIndices': '', - 'apm_oss.errorIndices': '', - 'apm_oss.onboardingIndices': '', - 'apm_oss.spanIndices': '', - 'apm_oss.transactionIndices': '', - 'apm_oss.metricsIndices': '', + sourcemap: '', + error: '', + onboarding: '', + span: '', + transaction: '', + metric: '', }, headers: { 'kbn-xsrf': true }, auth: { user: 'apm_power_user', pass: 'changeme' }, diff --git a/x-pack/plugins/apm/kibana.json b/x-pack/plugins/apm/kibana.json index 4e82d82d655b4..865358959ea72 100644 --- a/x-pack/plugins/apm/kibana.json +++ b/x-pack/plugins/apm/kibana.json @@ -8,7 +8,6 @@ "version": "8.0.0", "kibanaVersion": "kibana", "requiredPlugins": [ - "apmOss", "data", "embeddable", "features", diff --git a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx index 6685dddd87d7f..2e526eff04346 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx @@ -30,40 +30,40 @@ import { const APM_INDEX_LABELS = [ { - configurationName: 'apm_oss.sourcemapIndices', + configurationName: 'sourcemap', label: i18n.translate( 'xpack.apm.settings.apmIndices.sourcemapIndicesLabel', { defaultMessage: 'Sourcemap Indices' } ), }, { - configurationName: 'apm_oss.errorIndices', + configurationName: 'error', label: i18n.translate('xpack.apm.settings.apmIndices.errorIndicesLabel', { defaultMessage: 'Error Indices', }), }, { - configurationName: 'apm_oss.onboardingIndices', + configurationName: 'onboarding', label: i18n.translate( 'xpack.apm.settings.apmIndices.onboardingIndicesLabel', { defaultMessage: 'Onboarding Indices' } ), }, { - configurationName: 'apm_oss.spanIndices', + configurationName: 'span', label: i18n.translate('xpack.apm.settings.apmIndices.spanIndicesLabel', { defaultMessage: 'Span Indices', }), }, { - configurationName: 'apm_oss.transactionIndices', + configurationName: 'transaction', label: i18n.translate( 'xpack.apm.settings.apmIndices.transactionIndicesLabel', { defaultMessage: 'Transaction Indices' } ), }, { - configurationName: 'apm_oss.metricsIndices', + configurationName: 'metric', label: i18n.translate('xpack.apm.settings.apmIndices.metricsIndicesLabel', { defaultMessage: 'Metrics Indices', }), @@ -145,7 +145,7 @@ export function ApmIndices() { } ), }); - } catch (error) { + } catch (error: any) { notifications.toasts.addDanger({ title: i18n.translate( 'xpack.apm.settings.apmIndices.applyChanges.failed.title', @@ -215,7 +215,10 @@ export function ApmIndices() { { defaultMessage: 'Overrides {configurationName}: {defaultValue}', - values: { configurationName, defaultValue }, + values: { + configurationName: `xpack.apm.indices.${configurationName}`, + defaultValue, + }, } )} fullWidth diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/List/List.test.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/List/List.test.tsx index a2a92b7e16f8e..12fa1c955ccc8 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/List/List.test.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/List/List.test.tsx @@ -15,12 +15,6 @@ import props from './__fixtures__/props.json'; import { MemoryRouter } from 'react-router-dom'; import { EuiThemeProvider } from '../../../../../../../../src/plugins/kibana_react/common'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - describe('ErrorGroupOverview -> List', () => { beforeAll(() => { mockMoment(); diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/List/__snapshots__/List.test.tsx.snap b/x-pack/plugins/apm/public/components/app/error_group_overview/List/__snapshots__/List.test.tsx.snap index 890c692096a66..c8c7bf82dff04 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/List/__snapshots__/List.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/List/__snapshots__/List.test.tsx.snap @@ -56,7 +56,7 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = ` </div> <table className="euiTable euiTable--responsive" - id="generated-id" + id="__table_generated-id" tabIndex={-1} > <caption @@ -352,7 +352,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` </div> <table className="euiTable euiTable--responsive" - id="generated-id" + id="__table_generated-id" tabIndex={-1} > <caption @@ -1290,7 +1290,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` className="euiPagination__item" > <button - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-current={true} aria-label="Page 1 of 1" className="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiButtonEmpty-isDisabled euiPaginationButton euiPaginationButton-isActive euiPaginationButton--hideOnMobile" diff --git a/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_accordion.tsx b/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_accordion.tsx index de9c7f651019e..8f66658785b97 100644 --- a/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_accordion.tsx +++ b/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_accordion.tsx @@ -24,7 +24,6 @@ import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent'; import { AgentIcon } from '../../shared/agent_icon'; import { NewPackagePolicy } from '../apm_policy_form/typings'; import { getCommands } from '../../../tutorial/config_agent/commands/get_commands'; -import { CopyCommands } from '../../../tutorial/config_agent/copy_commands'; import { replaceTemplateStrings } from './replace_template_strings'; function AccordionButtonContent({ @@ -91,14 +90,9 @@ function TutorialConfigAgent({ policyDetails: { apmServerUrl, secretToken }, }); return ( - <EuiFlexGroup direction="column" gutterSize="s"> - <EuiFlexItem style={{ marginLeft: 'auto' }}> - <CopyCommands commands={commandBlock} /> - </EuiFlexItem> - <EuiFlexItem> - <EuiCodeBlock language="bash">{commandBlock}</EuiCodeBlock> - </EuiFlexItem> - </EuiFlexGroup> + <EuiCodeBlock isCopyable language="bash"> + {commandBlock} + </EuiCodeBlock> ); } @@ -153,23 +147,16 @@ export function AgentInstructionsAccordion({ <EuiSpacer size="s" /> <EuiText color="subdued" size="s"> {textPre && ( - <EuiFlexGroup justifyContent="spaceBetween"> - <EuiFlexItem grow={false}> - <InstructionsContent - markdown={replaceTemplateStrings(textPre, docLinks)} - /> - </EuiFlexItem> - {commandBlock && ( - <EuiFlexItem grow={false}> - <CopyCommands commands={commandBlock} /> - </EuiFlexItem> - )} - </EuiFlexGroup> + <InstructionsContent + markdown={replaceTemplateStrings(textPre, docLinks)} + /> )} {commandBlock && ( <> <EuiSpacer size="s" /> - <EuiCodeBlock language="bash">{commandBlock}</EuiCodeBlock> + <EuiCodeBlock isCopyable language="bash"> + {commandBlock} + </EuiCodeBlock> </> )} {customComponentName === 'TutorialConfigAgent' && ( diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.test.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.test.tsx index c73d312e0cf18..6bab77dbe4970 100644 --- a/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.test.tsx @@ -12,12 +12,6 @@ import { mountWithTheme } from '../../../utils/testHelpers'; import { Stackframe as StackframeComponent } from './Stackframe'; import stacktracesMock from './__fixtures__/stacktraces.json'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - describe('Stackframe', () => { describe('when stackframe has source lines', () => { let wrapper: ReactWrapper; diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap index e4674b3add880..15613af4daf98 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap @@ -35,7 +35,12 @@ exports[`ManagedTable should render a page-full of items, with defaults 1`] = ` ] } loading={false} - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } onChange={[Function]} pagination={ Object { @@ -85,7 +90,12 @@ exports[`ManagedTable should render when specifying initial values 1`] = ` ] } loading={false} - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } onChange={[Function]} pagination={ Object { diff --git a/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx b/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx index 617af6dae484d..abdab939f4a0a 100644 --- a/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx +++ b/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx @@ -100,7 +100,7 @@ const urlService = new UrlService({ getUrl: async ({ app, path }, { absolute }) => { return `${absolute ? 'http://localhost:8888' : ''}/app/${app}${path}`; }, - shortUrls: {} as any, + shortUrls: () => ({ get: () => {} } as any), }); const locator = urlService.locators.create(new MlLocatorDefinition()); diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/copy_commands.tsx b/x-pack/plugins/apm/public/tutorial/config_agent/copy_commands.tsx deleted file mode 100644 index c5261cfc1dc04..0000000000000 --- a/x-pack/plugins/apm/public/tutorial/config_agent/copy_commands.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { EuiButton, EuiCopy } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; - -interface Props { - commands: string; -} -export function CopyCommands({ commands }: Props) { - return ( - <EuiCopy textToCopy={commands}> - {(copy) => ( - <EuiButton size="s" onClick={copy}> - {i18n.translate('xpack.apm.tutorial.copySnippet', { - defaultMessage: 'Copy snippet', - })} - </EuiButton> - )} - </EuiCopy> - ); -} diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/index.tsx b/x-pack/plugins/apm/public/tutorial/config_agent/index.tsx index 5ff1fd7f42119..bce16ae6ef1f9 100644 --- a/x-pack/plugins/apm/public/tutorial/config_agent/index.tsx +++ b/x-pack/plugins/apm/public/tutorial/config_agent/index.tsx @@ -4,20 +4,13 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { - EuiCodeBlock, - EuiFlexGroup, - EuiFlexItem, - EuiLoadingSpinner, - EuiSpacer, -} from '@elastic/eui'; +import { EuiCodeBlock, EuiLoadingSpinner, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { HttpStart } from 'kibana/public'; import React, { useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { APIReturnType } from '../..//services/rest/createCallApmApi'; import { getCommands } from './commands/get_commands'; -import { CopyCommands } from './copy_commands'; import { getPolicyOptions, PolicyOption } from './get_policy_options'; import { PolicySelector } from './policy_selector'; @@ -136,27 +129,19 @@ function TutorialConfigAgent({ return ( <> - <EuiFlexGroup justifyContent="spaceBetween"> - <EuiFlexItem> - <PolicySelector - options={options} - selectedOption={selectedOption} - onChange={(newSelectedOption) => - setSelectedOption(newSelectedOption) - } - fleetLink={getFleetLink({ - isFleetEnabled: data.isFleetEnabled, - hasFleetAgents, - basePath, - })} - /> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <CopyCommands commands={commands} /> - </EuiFlexItem> - </EuiFlexGroup> + <PolicySelector + options={options} + selectedOption={selectedOption} + onChange={(newSelectedOption) => setSelectedOption(newSelectedOption)} + fleetLink={getFleetLink({ + isFleetEnabled: data.isFleetEnabled, + hasFleetAgents, + basePath, + })} + /> + <EuiSpacer /> - <EuiCodeBlock language="bash" data-test-subj="commands"> + <EuiCodeBlock isCopyable language="bash" data-test-subj="commands"> {commands} </EuiCodeBlock> </> diff --git a/x-pack/plugins/apm/public/utils/testHelpers.tsx b/x-pack/plugins/apm/public/utils/testHelpers.tsx index 8764ac48c5440..9ce7d2e4a52d9 100644 --- a/x-pack/plugins/apm/public/utils/testHelpers.tsx +++ b/x-pack/plugins/apm/public/utils/testHelpers.tsx @@ -119,14 +119,12 @@ interface MockSetup { config: APMConfig; uiFilters: UxUIFilters; indices: { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': string; - 'apm_oss.errorIndices': string; - 'apm_oss.onboardingIndices': string; - 'apm_oss.spanIndices': string; - 'apm_oss.transactionIndices': string; - 'apm_oss.metricsIndices': string; - /* eslint-enable @typescript-eslint/naming-convention */ + sourcemap: string; + error: string; + onboarding: string; + span: string; + transaction: string; + metric: string; apmAgentConfigurationIndex: string; apmCustomLinkIndex: string; }; @@ -178,14 +176,12 @@ export async function inspectSearchParams( ) as APMConfig, uiFilters: {}, indices: { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': 'myIndex', - 'apm_oss.errorIndices': 'myIndex', - 'apm_oss.onboardingIndices': 'myIndex', - 'apm_oss.spanIndices': 'myIndex', - 'apm_oss.transactionIndices': 'myIndex', - 'apm_oss.metricsIndices': 'myIndex', - /* eslint-enable @typescript-eslint/naming-convention */ + sourcemap: 'myIndex', + error: 'myIndex', + onboarding: 'myIndex', + span: 'myIndex', + transaction: 'myIndex', + metric: 'myIndex', apmAgentConfigurationIndex: 'myIndex', apmCustomLinkIndex: 'myIndex', }, diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md index 6ebe07d44683c..040e620ae91ca 100644 --- a/x-pack/plugins/apm/readme.md +++ b/x-pack/plugins/apm/readme.md @@ -1,31 +1,18 @@ # Documentation for APM UI developers -## Local environment setup +## Getting started +- [Local setup](./dev_docs/local_setup.md) +- [Testing (unit, api, e2e, storybook)](./dev_docs/testing.md) +- [Linting (typescript, eslint, prettier)](./dev_docs/linting.md) -[Local setup documentation](./dev_docs/local_setup.md) - -## Testing - -[Testing documentation](./dev_docs/testing.md) - -## Linting - -[Linting documentation](./dev_docs/linting.md) - -## Storybook - -**Start** -``` -yarn storybook apm -``` - -All files with a .stories.tsx extension will be loaded. You can access the development environment at http://localhost:9001. - -## Further resources +## APM concepts - [Queries and data model](./dev_docs/apm_queries.md) +- [Telemetry](./dev_docs/telemetry.md) +- [Routing and Linking](./dev_docs/routing_and_linking.md) + +## Tooling - [VSCode setup instructions](./dev_docs/vscode_setup.md) - [Github PR commands](./dev_docs/github_commands.md) -- [Routing and Linking](./dev_docs/routing_and_linking.md) -- [Telemetry](./dev_docs/telemetry.md) -- [Features flags](./dev_docs/feature_flags.md) + +## Other resources - [Official APM UI settings docs](https://www.elastic.co/guide/en/kibana/current/apm-settings-in-kibana.html) diff --git a/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts b/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts index a85bd007bc4f3..f3e2b48390468 100644 --- a/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts +++ b/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts @@ -38,14 +38,12 @@ export const readKibanaConfig = () => { }; return { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.transactionIndices': 'apm-*', - 'apm_oss.metricsIndices': 'apm-*', - 'apm_oss.errorIndices': 'apm-*', - 'apm_oss.spanIndices': 'apm-*', - 'apm_oss.onboardingIndices': 'apm-*', - 'apm_oss.sourcemapIndices': 'apm-*', - /* eslint-enable @typescript-eslint/naming-convention */ + 'xpack.apm.indices.transaction': 'traces-apm*,apm-*', + 'xpack.apm.indices.metric': 'metrics-apm*,apm-*', + 'xpack.apm.indices.error': 'logs-apm*,apm-*', + 'xpack.apm.indices.span': 'traces-apm*,apm-*', + 'xpack.apm.indices.onboarding': 'apm-*', + 'xpack.apm.indices.sourcemap': 'apm-*', 'elasticsearch.hosts': 'http://localhost:9200', ...loadedKibanaConfig, ...cliEsCredentials, diff --git a/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts b/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts index 0dab75cfba9c7..c900123c6cee9 100644 --- a/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts +++ b/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts @@ -78,7 +78,12 @@ async function uploadData() { collectTelemetryParams: { logger: console as unknown as Logger, indices: { - ...config, + transaction: config['xpack.apm.indices.transaction'], + metric: config['xpack.apm.indices.metric'], + error: config['xpack.apm.indices.error'], + span: config['xpack.apm.indices.span'], + onboarding: config['xpack.apm.indices.onboarding'], + sourcemap: config['xpack.apm.indices.sourcemap'], apmCustomLinkIndex: '.apm-custom-links', apmAgentConfigurationIndex: '.apm-agent-configuration', }, diff --git a/x-pack/plugins/apm/server/index.test.ts b/x-pack/plugins/apm/server/index.test.ts deleted file mode 100644 index be93557fea6fc..0000000000000 --- a/x-pack/plugins/apm/server/index.test.ts +++ /dev/null @@ -1,40 +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. - */ - -/* eslint-disable @typescript-eslint/naming-convention */ - -import { APMOSSConfig } from 'src/plugins/apm_oss/server'; -import { APMXPackConfig } from '.'; -import { mergeConfigs } from './index'; - -describe('mergeConfigs', () => { - it('merges the configs', () => { - const apmOssConfig = { - transactionIndices: 'apm-*-transaction-*', - spanIndices: 'apm-*-span-*', - errorIndices: 'apm-*-error-*', - metricsIndices: 'apm-*-metric-*', - } as APMOSSConfig; - - const apmConfig = { - ui: { enabled: false }, - enabled: true, - metricsInterval: 2000, - agent: { migrations: { enabled: true } }, - } as APMXPackConfig; - - expect(mergeConfigs(apmOssConfig, apmConfig)).toEqual({ - 'apm_oss.errorIndices': 'logs-apm*,apm-*-error-*', - 'apm_oss.metricsIndices': 'metrics-apm*,apm-*-metric-*', - 'apm_oss.spanIndices': 'traces-apm*,apm-*-span-*', - 'apm_oss.transactionIndices': 'traces-apm*,apm-*-transaction-*', - 'xpack.apm.metricsInterval': 2000, - 'xpack.apm.ui.enabled': false, - 'xpack.apm.agent.migrations.enabled': true, - }); - }); -}); diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index 22787b0301ce0..c0dffc50e4e4f 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -10,11 +10,12 @@ import { PluginConfigDescriptor, PluginInitializerContext, } from 'src/core/server'; -import { APMOSSConfig } from 'src/plugins/apm_oss/server'; import { maxSuggestions } from '../../observability/common'; import { SearchAggregatedTransactionSetting } from '../common/aggregated_transactions'; import { APMPlugin } from './plugin'; +// All options should be documented in the APM configuration settings: https://github.com/elastic/kibana/blob/master/docs/settings/apm-settings.asciidoc +// and be included on cloud allow list unless there are specific reasons not to const configSchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), serviceMapEnabled: schema.boolean({ defaultValue: true }), @@ -47,12 +48,37 @@ const configSchema = schema.object({ enabled: schema.boolean({ defaultValue: false }), }), }), + indices: schema.object({ + transaction: schema.string({ defaultValue: 'traces-apm*,apm-*' }), + span: schema.string({ defaultValue: 'traces-apm*,apm-*' }), + error: schema.string({ defaultValue: 'logs-apm*,apm-*' }), + metric: schema.string({ defaultValue: 'metrics-apm*,apm-*' }), + sourcemap: schema.string({ defaultValue: 'apm-*' }), + onboarding: schema.string({ defaultValue: 'apm-*' }), + }), }); // plugin config -export const config: PluginConfigDescriptor<APMXPackConfig> = { - deprecations: ({ deprecate, renameFromRoot }) => [ +export const config: PluginConfigDescriptor<APMConfig> = { + deprecations: ({ + deprecate, + renameFromRoot, + deprecateFromRoot, + unusedFromRoot, + }) => [ deprecate('enabled', '8.0.0'), + renameFromRoot( + 'apm_oss.transactionIndices', + 'xpack.apm.indices.transaction' + ), + renameFromRoot('apm_oss.spanIndices', 'xpack.apm.indices.span'), + renameFromRoot('apm_oss.errorIndices', 'xpack.apm.indices.error'), + renameFromRoot('apm_oss.metricsIndices', 'xpack.apm.indices.metric'), + renameFromRoot('apm_oss.sourcemapIndices', 'xpack.apm.indices.sourcemap'), + renameFromRoot('apm_oss.onboardingIndices', 'xpack.apm.indices.onboarding'), + deprecateFromRoot('apm_oss.enabled', '8.0.0'), + unusedFromRoot('apm_oss.fleetMode'), + unusedFromRoot('apm_oss.indexPattern'), renameFromRoot( 'xpack.apm.maxServiceEnvironments', `uiSettings.overrides[${maxSuggestions}]` @@ -70,69 +96,8 @@ export const config: PluginConfigDescriptor<APMXPackConfig> = { schema: configSchema, }; -export type APMXPackConfig = TypeOf<typeof configSchema>; -export type APMConfig = ReturnType<typeof mergeConfigs>; - -// plugin config and ui indices settings -// All options should be documented in the APM configuration settings: https://github.com/elastic/kibana/blob/master/docs/settings/apm-settings.asciidoc -// and be included on cloud allow list unless there are specific reasons not to -export function mergeConfigs( - apmOssConfig: APMOSSConfig, - apmConfig: APMXPackConfig -) { - const mergedConfig = { - /* eslint-disable @typescript-eslint/naming-convention */ - // TODO: Remove all apm_oss options by 8.0 - 'apm_oss.transactionIndices': apmOssConfig.transactionIndices, - 'apm_oss.spanIndices': apmOssConfig.spanIndices, - 'apm_oss.errorIndices': apmOssConfig.errorIndices, - 'apm_oss.metricsIndices': apmOssConfig.metricsIndices, - 'apm_oss.sourcemapIndices': apmOssConfig.sourcemapIndices, - 'apm_oss.onboardingIndices': apmOssConfig.onboardingIndices, - /* eslint-enable @typescript-eslint/naming-convention */ - 'xpack.apm.serviceMapEnabled': apmConfig.serviceMapEnabled, - 'xpack.apm.serviceMapFingerprintBucketSize': - apmConfig.serviceMapFingerprintBucketSize, - 'xpack.apm.serviceMapTraceIdBucketSize': - apmConfig.serviceMapTraceIdBucketSize, - 'xpack.apm.serviceMapFingerprintGlobalBucketSize': - apmConfig.serviceMapFingerprintGlobalBucketSize, - 'xpack.apm.serviceMapTraceIdGlobalBucketSize': - apmConfig.serviceMapTraceIdGlobalBucketSize, - 'xpack.apm.serviceMapMaxTracesPerRequest': - apmConfig.serviceMapMaxTracesPerRequest, - 'xpack.apm.ui.enabled': apmConfig.ui.enabled, - 'xpack.apm.ui.maxTraceItems': apmConfig.ui.maxTraceItems, - 'xpack.apm.ui.transactionGroupBucketSize': - apmConfig.ui.transactionGroupBucketSize, - 'xpack.apm.autocreateApmIndexPattern': apmConfig.autocreateApmIndexPattern, - 'xpack.apm.telemetryCollectionEnabled': - apmConfig.telemetryCollectionEnabled, - 'xpack.apm.searchAggregatedTransactions': - apmConfig.searchAggregatedTransactions, - 'xpack.apm.metricsInterval': apmConfig.metricsInterval, - 'xpack.apm.agent.migrations.enabled': apmConfig.agent.migrations.enabled, - }; - - // Add data stream indices to list of configured values - mergedConfig[ - 'apm_oss.transactionIndices' - ] = `traces-apm*,${mergedConfig['apm_oss.transactionIndices']}`; - - mergedConfig[ - 'apm_oss.spanIndices' - ] = `traces-apm*,${mergedConfig['apm_oss.spanIndices']}`; - - mergedConfig[ - 'apm_oss.errorIndices' - ] = `logs-apm*,${mergedConfig['apm_oss.errorIndices']}`; - - mergedConfig[ - 'apm_oss.metricsIndices' - ] = `metrics-apm*,${mergedConfig['apm_oss.metricsIndices']}`; - - return mergedConfig; -} +export type APMConfig = TypeOf<typeof configSchema>; +export type ApmIndicesConfigName = keyof APMConfig['indices']; export const plugin = (initContext: PluginInitializerContext) => new APMPlugin(initContext); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts index d1026b0b6ca8b..7fe2adcfe24d7 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts @@ -99,7 +99,7 @@ export function registerErrorCountAlertType({ }); const searchParams = { - index: indices['apm_oss.errorIndices'], + index: indices.error, size: 0, body: { query: { diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts index b383b4777eca4..df4de254346c9 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts @@ -115,12 +115,12 @@ export function registerTransactionDurationAlertType({ // to prevent (likely) unnecessary blocking request // in rule execution const searchAggregatedTransactions = - config['xpack.apm.searchAggregatedTransactions'] !== + config.searchAggregatedTransactions !== SearchAggregatedTransactionSetting.never; const index = searchAggregatedTransactions - ? indices['apm_oss.metricsIndices'] - : indices['apm_oss.transactionIndices']; + ? indices.metric + : indices.transaction; const field = getTransactionDurationFieldForAggregatedTransactions( searchAggregatedTransactions diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts index 6c59bcc4107b0..598487d02625a 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts @@ -110,12 +110,12 @@ export function registerTransactionErrorRateAlertType({ // to prevent (likely) unnecessary blocking request // in rule execution const searchAggregatedTransactions = - config['xpack.apm.searchAggregatedTransactions'] !== + config.searchAggregatedTransactions !== SearchAggregatedTransactionSetting.never; const index = searchAggregatedTransactions - ? indices['apm_oss.metricsIndices'] - : indices['apm_oss.transactionIndices']; + ? indices.metric + : indices.transaction; const searchParams = { index, diff --git a/x-pack/plugins/apm/server/lib/alerts/test_utils/index.ts b/x-pack/plugins/apm/server/lib/alerts/test_utils/index.ts index 5d5865bdd2289..22649a7010461 100644 --- a/x-pack/plugins/apm/server/lib/alerts/test_utils/index.ts +++ b/x-pack/plugins/apm/server/lib/alerts/test_utils/index.ts @@ -17,10 +17,10 @@ export const createRuleTypeMocks = () => { let alertExecutor: (...args: any[]) => Promise<any>; const mockedConfig$ = of({ - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.errorIndices': 'apm-*', - 'apm_oss.transactionIndices': 'apm-*', - /* eslint-enable @typescript-eslint/naming-convention */ + indices: { + error: 'apm-*', + transaction: 'apm-*', + }, } as APMConfig); const loggerMock = { diff --git a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts index 324202b207237..10758b6d90cdc 100644 --- a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts +++ b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts @@ -50,7 +50,7 @@ export async function createAnomalyDetectionJobs( `Creating ML anomaly detection jobs for environments: [${uniqueMlJobEnvs}].` ); - const indexPatternName = indices['apm_oss.metricsIndices']; + const indexPatternName = indices.metric; const responses = await Promise.all( uniqueMlJobEnvs.map((environment) => createAnomalyDetectionJob({ ml, environment, indexPatternName }) diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts index 4bfac442b4a3c..1e697ebdcae06 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts @@ -14,12 +14,10 @@ import { describe('data telemetry collection tasks', () => { const indices = { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.errorIndices': 'apm-8.0.0-error', - 'apm_oss.metricsIndices': 'apm-8.0.0-metric', - 'apm_oss.spanIndices': 'apm-8.0.0-span', - 'apm_oss.transactionIndices': 'apm-8.0.0-transaction', - /* eslint-enable @typescript-eslint/naming-convention */ + error: 'apm-8.0.0-error', + metric: 'apm-8.0.0-metric', + span: 'apm-8.0.0-span', + transaction: 'apm-8.0.0-transaction', } as ApmIndicesConfig; describe('environments', () => { diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts index d624c8527df86..8764223ad1ebb 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts @@ -78,7 +78,7 @@ export const tasks: TelemetryTask[] = [ }; const params = { - index: [indices['apm_oss.transactionIndices']], + index: [indices.transaction], body: { size: 0, timeout, @@ -138,7 +138,7 @@ export const tasks: TelemetryTask[] = [ // fixed date range for reliable results const lastTransaction = ( await search({ - index: indices['apm_oss.transactionIndices'], + index: indices.transaction, body: { query: { bool: { @@ -253,10 +253,10 @@ export const tasks: TelemetryTask[] = [ const response = await search({ index: [ - indices['apm_oss.errorIndices'], - indices['apm_oss.metricsIndices'], - indices['apm_oss.spanIndices'], - indices['apm_oss.transactionIndices'], + indices.error, + indices.metric, + indices.span, + indices.transaction, ], body: { size: 0, @@ -310,10 +310,10 @@ export const tasks: TelemetryTask[] = [ const response = await search({ index: [ - indices['apm_oss.errorIndices'], - indices['apm_oss.metricsIndices'], - indices['apm_oss.spanIndices'], - indices['apm_oss.transactionIndices'], + indices.error, + indices.metric, + indices.span, + indices.transaction, ], body: { size: 0, @@ -345,7 +345,7 @@ export const tasks: TelemetryTask[] = [ name: 'environments', executor: async ({ indices, search }) => { const response = await search({ - index: [indices['apm_oss.transactionIndices']], + index: [indices.transaction], body: { query: { bool: { @@ -426,12 +426,12 @@ export const tasks: TelemetryTask[] = [ name: 'processor_events', executor: async ({ indices, search }) => { const indicesByProcessorEvent = { - error: indices['apm_oss.errorIndices'], - metric: indices['apm_oss.metricsIndices'], - span: indices['apm_oss.spanIndices'], - transaction: indices['apm_oss.transactionIndices'], - onboarding: indices['apm_oss.onboardingIndices'], - sourcemap: indices['apm_oss.sourcemapIndices'], + error: indices.error, + metric: indices.metric, + span: indices.span, + transaction: indices.transaction, + onboarding: indices.onboarding, + sourcemap: indices.sourcemap, }; type ProcessorEvent = keyof typeof indicesByProcessorEvent; @@ -549,10 +549,10 @@ export const tasks: TelemetryTask[] = [ return prevJob.then(async (data) => { const response = await search({ index: [ - indices['apm_oss.errorIndices'], - indices['apm_oss.spanIndices'], - indices['apm_oss.metricsIndices'], - indices['apm_oss.transactionIndices'], + indices.error, + indices.span, + indices.metric, + indices.transaction, ], body: { size: 0, @@ -598,11 +598,7 @@ export const tasks: TelemetryTask[] = [ name: 'versions', executor: async ({ search, indices }) => { const response = await search({ - index: [ - indices['apm_oss.transactionIndices'], - indices['apm_oss.spanIndices'], - indices['apm_oss.errorIndices'], - ], + index: [indices.transaction, indices.span, indices.error], terminateAfter: 1, body: { query: { @@ -647,7 +643,7 @@ export const tasks: TelemetryTask[] = [ executor: async ({ search, indices }) => { const errorGroupsCount = ( await search({ - index: indices['apm_oss.errorIndices'], + index: indices.error, body: { size: 0, timeout, @@ -683,7 +679,7 @@ export const tasks: TelemetryTask[] = [ const transactionGroupsCount = ( await search({ - index: indices['apm_oss.transactionIndices'], + index: indices.transaction, body: { size: 0, timeout, @@ -719,7 +715,7 @@ export const tasks: TelemetryTask[] = [ const tracesPerDayCount = ( await search({ - index: indices['apm_oss.transactionIndices'], + index: indices.transaction, body: { query: { bool: { @@ -741,11 +737,7 @@ export const tasks: TelemetryTask[] = [ const servicesCount = ( await search({ - index: [ - indices['apm_oss.transactionIndices'], - indices['apm_oss.errorIndices'], - indices['apm_oss.metricsIndices'], - ], + index: [indices.transaction, indices.error, indices.metric], body: { size: 0, timeout, @@ -811,11 +803,7 @@ export const tasks: TelemetryTask[] = [ const data = await prevJob; const response = await search({ - index: [ - indices['apm_oss.errorIndices'], - indices['apm_oss.metricsIndices'], - indices['apm_oss.transactionIndices'], - ], + index: [indices.error, indices.metric, indices.transaction], body: { size: 0, timeout, @@ -1006,12 +994,12 @@ export const tasks: TelemetryTask[] = [ const response = await indicesStats({ index: [ indices.apmAgentConfigurationIndex, - indices['apm_oss.errorIndices'], - indices['apm_oss.metricsIndices'], - indices['apm_oss.onboardingIndices'], - indices['apm_oss.sourcemapIndices'], - indices['apm_oss.spanIndices'], - indices['apm_oss.transactionIndices'], + indices.error, + indices.metric, + indices.onboarding, + indices.sourcemap, + indices.span, + indices.transaction, ], }); diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.test.ts b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.test.ts index 809869e13de7f..871df10d9bafa 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.test.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.test.ts @@ -43,14 +43,12 @@ describe('get buckets', () => { } ) as APMConfig, indices: { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': 'apm-*', - 'apm_oss.errorIndices': 'apm-*', - 'apm_oss.onboardingIndices': 'apm-*', - 'apm_oss.spanIndices': 'apm-*', - 'apm_oss.transactionIndices': 'apm-*', - 'apm_oss.metricsIndices': 'apm-*', - /* eslint-enable @typescript-eslint/naming-convention */ + sourcemap: 'apm-*', + error: 'apm-*', + onboarding: 'apm-*', + span: 'apm-*', + transaction: 'apm-*', + metric: 'apm-*', apmAgentConfigurationIndex: '.apm-agent-configuration', apmCustomLinkIndex: '.apm-custom-link', }, diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.test.ts b/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.test.ts index f17224384842d..1fac873ced7be 100644 --- a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.test.ts @@ -58,8 +58,7 @@ describe('getIsUsingTransactionEvents', () => { describe('with config xpack.apm.searchAggregatedTransactions: never', () => { const config = { - 'xpack.apm.searchAggregatedTransactions': - SearchAggregatedTransactionSetting.never, + searchAggregatedTransactions: SearchAggregatedTransactionSetting.never, }; it('should be false', async () => { @@ -81,8 +80,7 @@ describe('getIsUsingTransactionEvents', () => { describe('with config xpack.apm.searchAggregatedTransactions: always', () => { const config = { - 'xpack.apm.searchAggregatedTransactions': - SearchAggregatedTransactionSetting.always, + searchAggregatedTransactions: SearchAggregatedTransactionSetting.always, }; it('should be false when kuery is empty', async () => { mock = await inspectSearchParams( @@ -164,8 +162,7 @@ describe('getIsUsingTransactionEvents', () => { describe('with config xpack.apm.searchAggregatedTransactions: auto', () => { const config = { - 'xpack.apm.searchAggregatedTransactions': - SearchAggregatedTransactionSetting.auto, + searchAggregatedTransactions: SearchAggregatedTransactionSetting.auto, }; it('should query for data once if metrics data found', async () => { diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.ts b/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.ts index 70df0959a63b6..66e9697ab7c91 100644 --- a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.ts +++ b/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.ts @@ -23,8 +23,7 @@ export async function getIsUsingTransactionEvents({ start?: number; end?: number; }): Promise<boolean> { - const searchAggregatedTransactions = - config['xpack.apm.searchAggregatedTransactions']; + const searchAggregatedTransactions = config.searchAggregatedTransactions; if ( searchAggregatedTransactions === SearchAggregatedTransactionSetting.never diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts b/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts index 478f3218ef38c..a58a95dd43fcc 100644 --- a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts @@ -63,8 +63,7 @@ export async function getSearchAggregatedTransactions({ apmEventClient: APMEventClient; kuery: string; }): Promise<boolean> { - const searchAggregatedTransactions = - config['xpack.apm.searchAggregatedTransactions']; + const searchAggregatedTransactions = config.searchAggregatedTransactions; if ( kuery || diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts index 4983d6d515944..5ef3786e9bde4 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -/* eslint-disable @typescript-eslint/naming-convention */ import { APMEventESSearchRequest } from '.'; import { ApmIndicesConfig } from '../../../settings/apm_indices/get_apm_indices'; import { unpackProcessorEvents } from './unpack_processor_events'; @@ -19,12 +18,12 @@ describe('unpackProcessorEvents', () => { } as APMEventESSearchRequest; const indices = { - 'apm_oss.transactionIndices': 'my-apm-*-transaction-*', - 'apm_oss.metricsIndices': 'my-apm-*-metric-*', - 'apm_oss.errorIndices': 'my-apm-*-error-*', - 'apm_oss.spanIndices': 'my-apm-*-span-*', - 'apm_oss.onboardingIndices': 'my-apm-*-onboarding-', - 'apm_oss.sourcemapIndices': 'my-apm-*-sourcemap-*', + transaction: 'my-apm-*-transaction-*', + metric: 'my-apm-*-metric-*', + error: 'my-apm-*-error-*', + span: 'my-apm-*-span-*', + onboarding: 'my-apm-*-onboarding-*', + sourcemap: 'my-apm-*-sourcemap-*', } as ApmIndicesConfig; res = unpackProcessorEvents(request, indices); diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts index 47a2b3fe7e5c8..582fe0374c5ca 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts @@ -13,19 +13,16 @@ import { ESFilter, } from '../../../../../../../../src/core/types/elasticsearch'; import { APMEventESSearchRequest, APMEventESTermsEnumRequest } from '.'; -import { - ApmIndicesConfig, - ApmIndicesName, -} from '../../../settings/apm_indices/get_apm_indices'; +import { ApmIndicesConfig } from '../../../settings/apm_indices/get_apm_indices'; -const processorEventIndexMap: Record<ProcessorEvent, ApmIndicesName> = { - [ProcessorEvent.transaction]: 'apm_oss.transactionIndices', - [ProcessorEvent.span]: 'apm_oss.spanIndices', - [ProcessorEvent.metric]: 'apm_oss.metricsIndices', - [ProcessorEvent.error]: 'apm_oss.errorIndices', +const processorEventIndexMap = { + [ProcessorEvent.transaction]: 'transaction', + [ProcessorEvent.span]: 'span', + [ProcessorEvent.metric]: 'metric', + [ProcessorEvent.error]: 'error', // TODO: should have its own config setting - [ProcessorEvent.profile]: 'apm_oss.transactionIndices', -}; + [ProcessorEvent.profile]: 'transaction', +} as const; export function unpackProcessorEvents( request: APMEventESSearchRequest | APMEventESTermsEnumRequest, diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts index 94e88a09ea35c..d5ff97c050d9d 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts @@ -10,19 +10,20 @@ import { APMConfig } from '../..'; import { APMRouteHandlerResources } from '../../routes/typings'; import { ProcessorEvent } from '../../../common/processor_event'; import { PROCESSOR_EVENT } from '../../../common/elasticsearch_fieldnames'; +import { getApmIndices } from '../settings/apm_indices/get_apm_indices'; +import { PromiseReturnType } from '../../../../observability/typings/common'; jest.mock('../settings/apm_indices/get_apm_indices', () => ({ - getApmIndices: async () => ({ - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': 'apm-*', - 'apm_oss.errorIndices': 'apm-*', - 'apm_oss.onboardingIndices': 'apm-*', - 'apm_oss.spanIndices': 'apm-*', - 'apm_oss.transactionIndices': 'apm-*', - 'apm_oss.metricsIndices': 'apm-*', - /* eslint-enable @typescript-eslint/naming-convention */ - apmAgentConfigurationIndex: 'apm-*', - }), + getApmIndices: async () => + ({ + sourcemap: 'apm-*', + error: 'apm-*', + onboarding: 'apm-*', + span: 'apm-*', + transaction: 'apm-*', + metric: 'apm-*', + apmAgentConfigurationIndex: 'apm-*', + } as PromiseReturnType<typeof getApmIndices>), })); jest.mock('../index_pattern/get_dynamic_index_pattern', () => ({ diff --git a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts index aae707c6e4689..83adab6ae6cbc 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -/* eslint-disable @typescript-eslint/naming-convention */ import { createStaticIndexPattern } from './create_static_index_pattern'; import { Setup } from '../helpers/setup_request'; import * as HistoricalAgentData from '../../routes/historical_data/has_historical_agent_data'; @@ -25,11 +24,11 @@ function getMockSavedObjectsClient(existingIndexPatternTitle: string) { const setup = { indices: { - 'apm_oss.transactionIndices': 'apm-*-transaction-*', - 'apm_oss.spanIndices': 'apm-*-span-*', - 'apm_oss.errorIndices': 'apm-*-error-*', - 'apm_oss.metricsIndices': 'apm-*-metrics-*', - }, + transaction: 'apm-*-transaction-*', + span: 'apm-*-span-*', + error: 'apm-*-error-*', + metric: 'apm-*-metrics-*', + } as APMConfig['indices'], } as unknown as Setup; describe('createStaticIndexPattern', () => { @@ -37,7 +36,7 @@ describe('createStaticIndexPattern', () => { const savedObjectsClient = getMockSavedObjectsClient('apm-*'); await createStaticIndexPattern({ setup, - config: { 'xpack.apm.autocreateApmIndexPattern': false } as APMConfig, + config: { autocreateApmIndexPattern: false } as APMConfig, savedObjectsClient, spaceId: 'default', }); @@ -54,7 +53,7 @@ describe('createStaticIndexPattern', () => { await createStaticIndexPattern({ setup, - config: { 'xpack.apm.autocreateApmIndexPattern': true } as APMConfig, + config: { autocreateApmIndexPattern: true } as APMConfig, savedObjectsClient, spaceId: 'default', }); @@ -71,7 +70,7 @@ describe('createStaticIndexPattern', () => { await createStaticIndexPattern({ setup, - config: { 'xpack.apm.autocreateApmIndexPattern': true } as APMConfig, + config: { autocreateApmIndexPattern: true } as APMConfig, savedObjectsClient, spaceId: 'default', }); @@ -91,9 +90,7 @@ describe('createStaticIndexPattern', () => { await createStaticIndexPattern({ setup, - config: { - 'xpack.apm.autocreateApmIndexPattern': true, - } as APMConfig, + config: { autocreateApmIndexPattern: true } as APMConfig, savedObjectsClient, spaceId: 'default', }); @@ -120,9 +117,7 @@ describe('createStaticIndexPattern', () => { await createStaticIndexPattern({ setup, - config: { - 'xpack.apm.autocreateApmIndexPattern': true, - } as APMConfig, + config: { autocreateApmIndexPattern: true } as APMConfig, savedObjectsClient, spaceId: 'default', }); diff --git a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts index 4f35e7e639151..26ae2ac337e88 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts @@ -34,7 +34,7 @@ export async function createStaticIndexPattern({ }): Promise<boolean> { return withApmSpan('create_static_index_pattern', async () => { // don't autocreate APM index pattern if it's been disabled via the config - if (!config['xpack.apm.autocreateApmIndexPattern']) { + if (!config.autocreateApmIndexPattern) { return false; } diff --git a/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.test.ts b/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.test.ts index 8103630157584..8b7444ffdf6fa 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.test.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.test.ts @@ -5,18 +5,16 @@ * 2.0. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices'; import { getApmIndexPatternTitle } from './get_apm_index_pattern_title'; describe('getApmIndexPatternTitle', () => { it('returns an index pattern title by combining existing indicies', () => { const title = getApmIndexPatternTitle({ - 'apm_oss.transactionIndices': 'apm-*-transaction-*', - 'apm_oss.spanIndices': 'apm-*-span-*', - 'apm_oss.errorIndices': 'apm-*-error-*', - 'apm_oss.metricsIndices': 'apm-*-metrics-*', + transaction: 'apm-*-transaction-*', + span: 'apm-*-span-*', + error: 'apm-*-error-*', + metric: 'apm-*-metrics-*', } as ApmIndicesConfig); expect(title).toBe( 'apm-*-transaction-*,apm-*-span-*,apm-*-error-*,apm-*-metrics-*' @@ -25,10 +23,10 @@ describe('getApmIndexPatternTitle', () => { it('removes duplicates', () => { const title = getApmIndexPatternTitle({ - 'apm_oss.transactionIndices': 'apm-*', - 'apm_oss.spanIndices': 'apm-*', - 'apm_oss.errorIndices': 'apm-*', - 'apm_oss.metricsIndices': 'apm-*', + transaction: 'apm-*', + span: 'apm-*', + error: 'apm-*', + metric: 'apm-*', } as ApmIndicesConfig); expect(title).toBe('apm-*'); }); diff --git a/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.ts b/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.ts index e65f200130e9a..5e055ff1c2fdc 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/get_apm_index_pattern_title.ts @@ -10,9 +10,9 @@ import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices'; export function getApmIndexPatternTitle(apmIndicesConfig: ApmIndicesConfig) { return uniq([ - apmIndicesConfig['apm_oss.transactionIndices'], - apmIndicesConfig['apm_oss.spanIndices'], - apmIndicesConfig['apm_oss.errorIndices'], - apmIndicesConfig['apm_oss.metricsIndices'], + apmIndicesConfig.transaction, + apmIndicesConfig.span, + apmIndicesConfig.error, + apmIndicesConfig.metric, ]).join(','); } diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts index ba35836452122..06138931c004e 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts @@ -85,7 +85,7 @@ export async function fetchAndTransformGcMetrics({ date_histogram: getMetricsDateHistogramParams({ start, end, - metricsInterval: config['xpack.apm.metricsInterval'], + metricsInterval: config.metricsInterval, }), aggs: { // get the max value diff --git a/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts b/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts index a3fce0368f4a5..581a0782e4d72 100644 --- a/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts +++ b/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts @@ -99,7 +99,7 @@ export async function fetchAndTransformMetrics<T extends MetricAggs>({ date_histogram: getMetricsDateHistogramParams({ start, end, - metricsInterval: config['xpack.apm.metricsInterval'], + metricsInterval: config.metricsInterval, }), aggs, }, diff --git a/x-pack/plugins/apm/server/lib/rum_client/has_rum_data.ts b/x-pack/plugins/apm/server/lib/rum_client/has_rum_data.ts index 9409e94fa9ba9..ba35ac5c5c89c 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/has_rum_data.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/has_rum_data.ts @@ -56,7 +56,7 @@ export async function hasRumData({ const response = await apmEventClient.search('has_rum_data', params); return { - indices: setup.indices['apm_oss.transactionIndices']!, + indices: setup.indices.transaction, hasData: response.hits.total.value > 0, serviceName: response.aggregations?.services?.mostTraffic?.buckets?.[0]?.key, @@ -65,7 +65,7 @@ export async function hasRumData({ return { hasData: false, serviceName: undefined, - indices: setup.indices['apm_oss.transactionIndices']!, + indices: setup.indices.transaction, }; } } diff --git a/x-pack/plugins/apm/server/lib/search_strategies/failed_transactions_correlations/failed_transactions_correlations_search_service.ts b/x-pack/plugins/apm/server/lib/search_strategies/failed_transactions_correlations/failed_transactions_correlations_search_service.ts index 02ba0a8514b62..239cf39f15ffe 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/failed_transactions_correlations/failed_transactions_correlations_search_service.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/failed_transactions_correlations/failed_transactions_correlations_search_service.ts @@ -65,7 +65,7 @@ export const failedTransactionsCorrelationsSearchServiceProvider: FailedTransact const params: FailedTransactionsCorrelationsRequestParams & SearchStrategyServerParams = { ...searchServiceParams, - index: indices['apm_oss.transactionIndices'], + index: indices.transaction, includeFrozen, }; diff --git a/x-pack/plugins/apm/server/lib/search_strategies/latency_correlations/latency_correlations_search_service.ts b/x-pack/plugins/apm/server/lib/search_strategies/latency_correlations/latency_correlations_search_service.ts index 7e420c821a746..91f4a0d3349a4 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/latency_correlations/latency_correlations_search_service.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/latency_correlations/latency_correlations_search_service.ts @@ -67,7 +67,7 @@ export const latencyCorrelationsSearchServiceProvider: LatencyCorrelationsSearch const indices = await getApmIndices(); params = { ...searchServiceParams, - index: indices['apm_oss.transactionIndices'], + index: indices.transaction, includeFrozen, }; diff --git a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.test.ts b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.test.ts index 25ce39cbcf17b..ffc86c7ef6c32 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.test.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.test.ts @@ -106,8 +106,8 @@ describe('query_histogram_range_steps', () => { ); expect(resp.length).toEqual(100); - expect(resp[0]).toEqual(9.260965422132594); - expect(resp[99]).toEqual(18521.930844265193); + expect(resp[0]).toEqual(9); + expect(resp[99]).toEqual(18522); expect(esClientSearchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.ts b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.ts index 973787833577c..790919d193028 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_histogram_range_steps.ts @@ -19,10 +19,11 @@ import { getRequestBase } from './get_request_base'; const getHistogramRangeSteps = (min: number, max: number, steps: number) => { // A d3 based scale function as a helper to get equally distributed bins on a log scale. + // We round the final values because the ES range agg we use won't accept numbers with decimals for `transaction.duration.us`. const logFn = scaleLog().domain([min, max]).range([1, steps]); return [...Array(steps).keys()] .map(logFn.invert) - .map((d) => (isNaN(d) ? 0 : d)); + .map((d) => (isNaN(d) ? 0 : Math.round(d))); }; export const getHistogramIntervalRequest = ( diff --git a/x-pack/plugins/apm/server/lib/search_strategies/search_strategy_provider.test.ts b/x-pack/plugins/apm/server/lib/search_strategies/search_strategy_provider.test.ts index 6e03c879f9b97..8a9d04df32036 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/search_strategy_provider.test.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/search_strategy_provider.test.ts @@ -90,10 +90,7 @@ const clientSearchMock = ( }; const getApmIndicesMock = async () => - ({ - // eslint-disable-next-line @typescript-eslint/naming-convention - 'apm_oss.transactionIndices': 'apm-*', - } as ApmIndicesConfig); + ({ transaction: 'apm-*' } as ApmIndicesConfig); describe('APM Correlations search strategy', () => { describe('strategy interface', () => { diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts index 2497a85c0c774..ae511d0fed8f8 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts @@ -53,10 +53,7 @@ async function getConnectionData({ end, }); - const chunks = chunk( - traceIds, - setup.config['xpack.apm.serviceMapMaxTracesPerRequest'] - ); + const chunks = chunk(traceIds, setup.config.serviceMapMaxTracesPerRequest); const init = { connections: [], diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts index 2129606e69fc3..afb88189a5fd2 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts @@ -70,9 +70,7 @@ describe('getServiceMapServiceNodeInfo', () => { indices: {}, start: 1593460053026000, end: 1593497863217000, - config: { - 'xpack.apm.metricsInterval': 30, - }, + config: { metricsInterval: 30 }, uiFilters: { environment: 'test environment' }, } as unknown as Setup; const serviceName = 'test service name'; diff --git a/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts b/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts index c1c11f7bf639a..7e16e69498e7c 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts @@ -60,13 +60,11 @@ export async function getTraceSampleIds({ query.bool.filter.push(...environmentQuery(environment)); const fingerprintBucketSize = serviceName - ? config['xpack.apm.serviceMapFingerprintBucketSize'] - : config['xpack.apm.serviceMapFingerprintGlobalBucketSize']; - + ? config.serviceMapFingerprintBucketSize + : config.serviceMapFingerprintGlobalBucketSize; const traceIdBucketSize = serviceName - ? config['xpack.apm.serviceMapTraceIdBucketSize'] - : config['xpack.apm.serviceMapTraceIdGlobalBucketSize']; - + ? config.serviceMapTraceIdBucketSize + : config.serviceMapTraceIdGlobalBucketSize; const samplerShardSize = traceIdBucketSize * 10; const params = { @@ -137,8 +135,7 @@ export async function getTraceSampleIds({ 'get_trace_sample_ids', params ); - // make sure at least one trace per composite/connection bucket - // is queried + // make sure at least one trace per composite/connection bucket is queried const traceIdsWithPriority = tracesSampleResponse.aggregations?.connections.buckets.flatMap((bucket) => bucket.sample.trace_ids.buckets.map((sampleDocBucket, index) => ({ diff --git a/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts b/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts index a51f4c4e0fb7d..ec76e0d35e5c0 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts @@ -17,6 +17,7 @@ import { Coordinate } from '../../../../typings/timeseries'; import { kqlQuery, rangeQuery } from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { + getDocumentTypeFilterForAggregatedTransactions, getProcessorEventForAggregatedTransactions, getTransactionDurationFieldForAggregatedTransactions, } from '../../helpers/aggregated_transactions'; @@ -108,9 +109,15 @@ export async function getServiceInstancesTransactionStatistics< filter: [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, + ...getDocumentTypeFilterForAggregatedTransactions( + searchAggregatedTransactions + ), ...rangeQuery(start, end), ...environmentQuery(environment), ...kqlQuery(kuery), + ...getDocumentTypeFilterForAggregatedTransactions( + searchAggregatedTransactions + ), ...(isComparisonSearch && serviceNodeIds ? [{ terms: { [SERVICE_NODE_NAME]: serviceNodeIds } }] : []), diff --git a/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts b/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts index d5a2006060395..fbc1e2880495b 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts @@ -57,7 +57,7 @@ export async function getServiceTransactionGroups({ end: number; }) { const { apmEventClient, config } = setup; - const bucketSize = config['xpack.apm.ui.transactionGroupBucketSize']; + const bucketSize = config.ui.transactionGroupBucketSize; const field = getTransactionDurationFieldForAggregatedTransactions( searchAggregatedTransactions diff --git a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts index 0ade96682b362..107493af1a0c0 100644 --- a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { merge } from 'lodash'; - import { SavedObjectsClient } from 'src/core/server'; import { PromiseReturnType } from '../../../../../observability/typings/common'; import { @@ -22,8 +20,6 @@ export { ApmIndicesConfig }; type ISavedObjectsClient = Pick<SavedObjectsClient, 'get'>; -export type ApmIndicesName = keyof ApmIndicesConfig; - async function getApmIndicesSavedObject( savedObjectsClient: ISavedObjectsClient ) { @@ -38,14 +34,12 @@ async function getApmIndicesSavedObject( export function getApmIndicesConfig(config: APMConfig): ApmIndicesConfig { return { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': config['apm_oss.sourcemapIndices'], - 'apm_oss.errorIndices': config['apm_oss.errorIndices'], - 'apm_oss.onboardingIndices': config['apm_oss.onboardingIndices'], - 'apm_oss.spanIndices': config['apm_oss.spanIndices'], - 'apm_oss.transactionIndices': config['apm_oss.transactionIndices'], - 'apm_oss.metricsIndices': config['apm_oss.metricsIndices'], - /* eslint-enable @typescript-eslint/naming-convention */ + sourcemap: config.indices.sourcemap, + error: config.indices.error, + onboarding: config.indices.onboarding, + span: config.indices.span, + transaction: config.indices.transaction, + metric: config.indices.metric, // system indices, not configurable apmAgentConfigurationIndex: '.apm-agent-configuration', apmCustomLinkIndex: '.apm-custom-link', @@ -64,21 +58,12 @@ export async function getApmIndices({ savedObjectsClient ); const apmIndicesConfig = getApmIndicesConfig(config); - return merge({}, apmIndicesConfig, apmIndicesSavedObject); + return { ...apmIndicesConfig, ...apmIndicesSavedObject }; } catch (error) { return getApmIndicesConfig(config); } } -const APM_UI_INDICES: ApmIndicesName[] = [ - 'apm_oss.sourcemapIndices', - 'apm_oss.errorIndices', - 'apm_oss.onboardingIndices', - 'apm_oss.spanIndices', - 'apm_oss.transactionIndices', - 'apm_oss.metricsIndices', -]; - export async function getApmIndexSettings({ context, config, @@ -88,7 +73,7 @@ export async function getApmIndexSettings({ apmIndicesSavedObject = await getApmIndicesSavedObject( context.core.savedObjects.client ); - } catch (error) { + } catch (error: any) { if (error.output && error.output.statusCode === 404) { apmIndicesSavedObject = {}; } else { @@ -97,7 +82,11 @@ export async function getApmIndexSettings({ } const apmIndicesConfig = getApmIndicesConfig(config); - return APM_UI_INDICES.map((configurationName) => ({ + const apmIndices = Object.keys(config.indices) as Array< + keyof typeof config.indices + >; + + return apmIndices.map((configurationName) => ({ configurationName, defaultValue: apmIndicesConfig[configurationName], // value defined in kibana[.dev].yml savedValue: apmIndicesSavedObject[configurationName], // value saved via Saved Objects service diff --git a/x-pack/plugins/apm/server/lib/traces/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/traces/__snapshots__/queries.test.ts.snap index 53318fe5fe594..ea8f39f9d9b6d 100644 --- a/x-pack/plugins/apm/server/lib/traces/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/traces/__snapshots__/queries.test.ts.snap @@ -37,7 +37,7 @@ Object { }, }, }, - "size": "myIndex", + "size": 1000, }, } `; diff --git a/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts b/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts index e940100edcf52..60a28fd9abdbd 100644 --- a/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts +++ b/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts @@ -24,7 +24,7 @@ export async function getTraceItems( end: number ) { const { apmEventClient, config } = setup; - const maxTraceItems = config['xpack.apm.ui.maxTraceItems']; + const maxTraceItems = config.ui.maxTraceItems; const excludedLogLevels = ['debug', 'info', 'warning']; const errorResponsePromise = apmEventClient.search('get_errors_docs', { @@ -80,9 +80,5 @@ export async function getTraceItems( const traceDocs = traceResponse.hits.hits.map((hit) => hit._source); const errorDocs = errorResponse.hits.hits.map((hit) => hit._source); - return { - exceedsMax, - traceDocs, - errorDocs, - }; + return { exceedsMax, traceDocs, errorDocs }; } diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts index 6e9d0aad96b71..76cabd3e3af93 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts @@ -11,16 +11,15 @@ import noDataResponse from './mock_responses/no_data.json'; import dataResponse from './mock_responses/data.json'; import { APMConfig } from '../../..'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; - -const mockIndices = { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': 'myIndex', - 'apm_oss.errorIndices': 'myIndex', - 'apm_oss.onboardingIndices': 'myIndex', - 'apm_oss.spanIndices': 'myIndex', - 'apm_oss.transactionIndices': 'myIndex', - 'apm_oss.metricsIndices': 'myIndex', - /* eslint-enable @typescript-eslint/naming-convention */ +import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices'; + +const mockIndices: ApmIndicesConfig = { + sourcemap: 'myIndex', + error: 'myIndex', + onboarding: 'myIndex', + span: 'myIndex', + transaction: 'myIndex', + metric: 'myIndex', apmAgentConfigurationIndex: 'myIndex', apmCustomLinkIndex: 'myIndex', }; diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts index 62277dba8ac29..a5c11776c70b0 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts @@ -124,7 +124,7 @@ export async function getTransactionBreakdown({ date_histogram: getMetricsDateHistogramParams({ start, end, - metricsInterval: config['xpack.apm.metricsInterval'], + metricsInterval: config.metricsInterval, }), aggs: subAggs, }, diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index 2296227de2a33..d2d8dbf602364 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -5,8 +5,7 @@ * 2.0. */ -import { combineLatest } from 'rxjs'; -import { map, take } from 'rxjs/operators'; +import { take } from 'rxjs/operators'; import { CoreSetup, CoreStart, @@ -19,8 +18,7 @@ import { isEmpty, mapValues } from 'lodash'; import { SavedObjectsClient } from '../../../../src/core/server'; import { mappingFromFieldMap } from '../../rule_registry/common/mapping_from_field_map'; import { Dataset } from '../../rule_registry/server'; -import { APMConfig, APMXPackConfig, APM_SERVER_FEATURE_ID } from '.'; -import { mergeConfigs } from './index'; +import { APMConfig, APM_SERVER_FEATURE_ID } from '.'; import { UI_SETTINGS } from '../../../../src/plugins/data/common'; import { APM_FEATURE, registerFeaturesUsage } from './feature'; import { registerApmAlerts } from './lib/alerts/register_apm_alerts'; @@ -73,29 +71,23 @@ export class APMPlugin plugins: Omit<APMPluginSetupDependencies, 'core'> ) { this.logger = this.initContext.logger.get(); - const config$ = this.initContext.config.create<APMXPackConfig>(); - const mergedConfig$ = combineLatest(plugins.apmOss.config$, config$).pipe( - map(([apmOssConfig, apmConfig]) => mergeConfigs(apmOssConfig, apmConfig)) - ); + const config$ = this.initContext.config.create<APMConfig>(); core.savedObjects.registerType(apmIndices); core.savedObjects.registerType(apmTelemetry); core.savedObjects.registerType(apmServerSettings); - const currentConfig = mergeConfigs( - plugins.apmOss.config, - this.initContext.config.get<APMXPackConfig>() - ); + const currentConfig = this.initContext.config.get<APMConfig>(); this.currentConfig = currentConfig; if ( plugins.taskManager && plugins.usageCollection && - currentConfig['xpack.apm.telemetryCollectionEnabled'] + currentConfig.telemetryCollectionEnabled ) { createApmTelemetry({ core, - config$: mergedConfig$, + config$, usageCollector: plugins.usageCollection, taskManager: plugins.taskManager, logger: this.logger, @@ -156,7 +148,7 @@ export class APMPlugin const boundGetApmIndices = async () => getApmIndices({ savedObjectsClient: await getInternalSavedObjectsClient(core), - config: await mergedConfig$.pipe(take(1)).toPromise(), + config: await config$.pipe(take(1)).toPromise(), }); boundGetApmIndices().then((indices) => { @@ -193,7 +185,7 @@ export class APMPlugin ruleDataClient, alerting: plugins.alerting, ml: plugins.ml, - config$: mergedConfig$, + config$, logger: this.logger!.get('rule'), }); } @@ -231,7 +223,7 @@ export class APMPlugin }); return { - config$: mergedConfig$, + config$, getApmIndices: boundGetApmIndices, createApmEventClient: async ({ request, diff --git a/x-pack/plugins/apm/server/routes/fleet.ts b/x-pack/plugins/apm/server/routes/fleet.ts index d8097228df0dc..2884c08ceb9a1 100644 --- a/x-pack/plugins/apm/server/routes/fleet.ts +++ b/x-pack/plugins/apm/server/routes/fleet.ts @@ -129,8 +129,7 @@ const getMigrationCheckRoute = createApmServerRoute({ options: { tags: ['access:apm'] }, handler: async (resources) => { const { plugins, context, config, request } = resources; - const cloudApmMigrationEnabled = - config['xpack.apm.agent.migrations.enabled']; + const cloudApmMigrationEnabled = config.agent.migrations.enabled; if (!plugins.fleet || !plugins.security) { throw Boom.internal(FLEET_SECURITY_REQUIRED_MESSAGE); } @@ -158,8 +157,7 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({ options: { tags: ['access:apm', 'access:apm_write'] }, handler: async (resources) => { const { plugins, context, config, request, logger } = resources; - const cloudApmMigrationEnabled = - config['xpack.apm.agent.migrations.enabled']; + const cloudApmMigrationEnabled = config.agent.migrations.enabled; if (!plugins.fleet || !plugins.security) { throw Boom.internal(FLEET_SECURITY_REQUIRED_MESSAGE); } diff --git a/x-pack/plugins/apm/server/routes/service_map.ts b/x-pack/plugins/apm/server/routes/service_map.ts index f9062ac13e049..17fb9d7c98c5f 100644 --- a/x-pack/plugins/apm/server/routes/service_map.ts +++ b/x-pack/plugins/apm/server/routes/service_map.ts @@ -33,7 +33,7 @@ const serviceMapRoute = createApmServerRoute({ options: { tags: ['access:apm'] }, handler: async (resources) => { const { config, context, params, logger } = resources; - if (!config['xpack.apm.serviceMapEnabled']) { + if (!config.serviceMapEnabled) { throw Boom.notFound(); } if (!isActivePlatinumLicense(context.licensing.license)) { @@ -81,7 +81,7 @@ const serviceMapServiceNodeRoute = createApmServerRoute({ handler: async (resources) => { const { config, context, params } = resources; - if (!config['xpack.apm.serviceMapEnabled']) { + if (!config.serviceMapEnabled) { throw Boom.notFound(); } if (!isActivePlatinumLicense(context.licensing.license)) { @@ -125,7 +125,7 @@ const serviceMapBackendNodeRoute = createApmServerRoute({ handler: async (resources) => { const { config, context, params } = resources; - if (!config['xpack.apm.serviceMapEnabled']) { + if (!config.serviceMapEnabled) { throw Boom.notFound(); } if (!isActivePlatinumLicense(context.licensing.license)) { diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices.ts index 1cba5f972c27e..156f4d1af0bb2 100644 --- a/x-pack/plugins/apm/server/routes/settings/apm_indices.ts +++ b/x-pack/plugins/apm/server/routes/settings/apm_indices.ts @@ -13,6 +13,7 @@ import { getApmIndexSettings, } from '../../lib/settings/apm_indices/get_apm_indices'; import { saveApmIndices } from '../../lib/settings/apm_indices/save_apm_indices'; +import { APMConfig } from '../..'; // get list of apm indices and values const apmIndexSettingsRoute = createApmServerRoute({ @@ -37,6 +38,10 @@ const apmIndicesRoute = createApmServerRoute({ }, }); +type SaveApmIndicesBodySchema = { + [Property in keyof APMConfig['indices']]: t.StringC; +}; + // save ui indices const saveApmIndicesRoute = createApmServerRoute({ endpoint: 'POST /internal/apm/settings/apm-indices/save', @@ -45,15 +50,13 @@ const saveApmIndicesRoute = createApmServerRoute({ }, params: t.type({ body: t.partial({ - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': t.string, - 'apm_oss.errorIndices': t.string, - 'apm_oss.onboardingIndices': t.string, - 'apm_oss.spanIndices': t.string, - 'apm_oss.transactionIndices': t.string, - 'apm_oss.metricsIndices': t.string, - /* eslint-enable @typescript-eslint/naming-convention */ - }), + sourcemap: t.string, + error: t.string, + onboarding: t.string, + span: t.string, + transaction: t.string, + metric: t.string, + } as SaveApmIndicesBodySchema), }), handler: async (resources) => { const { params, context } = resources; diff --git a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts b/x-pack/plugins/apm/server/saved_objects/apm_indices.ts index df5267023ae89..4aa6c4953056a 100644 --- a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts +++ b/x-pack/plugins/apm/server/saved_objects/apm_indices.ts @@ -7,34 +7,24 @@ import { SavedObjectsType } from 'src/core/server'; import { i18n } from '@kbn/i18n'; +import { updateApmOssIndexPaths } from './migrations/update_apm_oss_index_paths'; +import { ApmIndicesConfigName } from '..'; + +const properties: { [Property in ApmIndicesConfigName]: { type: 'keyword' } } = + { + sourcemap: { type: 'keyword' }, + error: { type: 'keyword' }, + onboarding: { type: 'keyword' }, + span: { type: 'keyword' }, + transaction: { type: 'keyword' }, + metric: { type: 'keyword' }, + }; export const apmIndices: SavedObjectsType = { name: 'apm-indices', hidden: false, namespaceType: 'agnostic', - mappings: { - properties: { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': { - type: 'keyword', - }, - 'apm_oss.errorIndices': { - type: 'keyword', - }, - 'apm_oss.onboardingIndices': { - type: 'keyword', - }, - 'apm_oss.spanIndices': { - type: 'keyword', - }, - 'apm_oss.transactionIndices': { - type: 'keyword', - }, - 'apm_oss.metricsIndices': { - type: 'keyword', - }, - }, - }, + mappings: { properties }, management: { importableAndExportable: true, icon: 'apmApp', @@ -43,4 +33,10 @@ export const apmIndices: SavedObjectsType = { defaultMessage: 'APM Settings - Index', }), }, + migrations: { + '7.16.0': (doc) => { + const attributes = updateApmOssIndexPaths(doc.attributes); + return { ...doc, attributes }; + }, + }, }; diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts b/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts new file mode 100644 index 0000000000000..72ba40db0ce05 --- /dev/null +++ b/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +const apmIndexConfigs = [ + ['sourcemap', 'apm_oss.sourcemapIndices'], + ['error', 'apm_oss.errorIndices'], + ['onboarding', 'apm_oss.onboardingIndices'], + ['span', 'apm_oss.spanIndices'], + ['transaction', 'apm_oss.transactionIndices'], + ['metric', 'apm_oss.metricsIndices'], +] as const; + +type ApmIndexConfigs = typeof apmIndexConfigs[number][0]; +type ApmIndicesSavedObjectAttributes = Partial<{ + [Property in ApmIndexConfigs]: string; +}>; +type DeprecatedApmIndexConfigPaths = typeof apmIndexConfigs[number][1]; +type DeprecatedApmIndicesSavedObjectAttributes = Partial<{ + [Property in DeprecatedApmIndexConfigPaths]: string; +}>; + +export function updateApmOssIndexPaths( + attributes: DeprecatedApmIndicesSavedObjectAttributes +) { + return apmIndexConfigs.reduce((attrs, [configPath, deprecatedConfigPath]) => { + const indexConfig: string | undefined = attributes[deprecatedConfigPath]; + if (indexConfig) { + attrs[configPath] = indexConfig; + } + return attrs; + }, {} as ApmIndicesSavedObjectAttributes); +} diff --git a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts index fb9fbae33ac82..ba99b0624c441 100644 --- a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts +++ b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts @@ -37,13 +37,7 @@ export function onPremInstructions({ apmConfig, isFleetPluginEnabled, }: { - apmConfig: Pick< - APMConfig, - | 'apm_oss.errorIndices' - | 'apm_oss.transactionIndices' - | 'apm_oss.metricsIndices' - | 'apm_oss.onboardingIndices' - >; + apmConfig: APMConfig; isFleetPluginEnabled: boolean; }): InstructionsSchema { const EDIT_CONFIG = createEditConfig(); @@ -76,7 +70,12 @@ export function onPremInstructions({ { id: INSTRUCTION_VARIANT.FLEET, instructions: [ - { customComponentName: 'TutorialFleetInstructions' }, + { + title: i18n.translate('xpack.apm.tutorial.fleet.title', { + defaultMessage: 'Fleet', + }), + customComponentName: 'TutorialFleetInstructions', + }, ], }, ] @@ -144,7 +143,7 @@ export function onPremInstructions({ } ), esHitsCheck: { - index: apmConfig['apm_oss.onboardingIndices'], + index: apmConfig.indices.onboarding, query: { bool: { filter: [ @@ -237,9 +236,9 @@ export function onPremInstructions({ ), esHitsCheck: { index: [ - apmConfig['apm_oss.errorIndices'], - apmConfig['apm_oss.transactionIndices'], - apmConfig['apm_oss.metricsIndices'], + apmConfig.indices.error, + apmConfig.indices.transaction, + apmConfig.indices.metric, ], query: { bool: { diff --git a/x-pack/plugins/apm/server/tutorial/index.ts b/x-pack/plugins/apm/server/tutorial/index.ts index 66e6ffaed95a8..5caf2b4372483 100644 --- a/x-pack/plugins/apm/server/tutorial/index.ts +++ b/x-pack/plugins/apm/server/tutorial/index.ts @@ -67,7 +67,7 @@ export const tutorialProvider = ], }; - if (apmConfig['xpack.apm.ui.enabled']) { + if (apmConfig.ui.enabled) { // @ts-expect-error artifacts.application is readonly artifacts.application = { path: '/app/apm', diff --git a/x-pack/plugins/apm/server/types.ts b/x-pack/plugins/apm/server/types.ts index 325891d8c1d33..c686c42beb6ef 100644 --- a/x-pack/plugins/apm/server/types.ts +++ b/x-pack/plugins/apm/server/types.ts @@ -16,7 +16,6 @@ import { PluginStart as DataPluginStart, } from '../../../../src/plugins/data/server'; import { SpacesPluginSetup, SpacesPluginStart } from '../../spaces/server'; -import { APMOSSPluginSetup } from '../../../../src/plugins/apm_oss/server'; import { HomeServerPluginSetup, HomeServerPluginStart, @@ -71,10 +70,6 @@ interface DependencyMap { setup: SpacesPluginSetup; start: SpacesPluginStart; }; - apmOss: { - setup: APMOSSPluginSetup; - start: undefined; - }; home: { setup: HomeServerPluginSetup; start: HomeServerPluginStart; @@ -135,7 +130,6 @@ interface DependencyMap { const requiredDependencies = [ 'features', - 'apmOss', 'data', 'licensing', 'triggersActionsUi', diff --git a/x-pack/plugins/apm/server/utils/test_helpers.tsx b/x-pack/plugins/apm/server/utils/test_helpers.tsx index 7b6b549e07c8d..5cf5016aec2e9 100644 --- a/x-pack/plugins/apm/server/utils/test_helpers.tsx +++ b/x-pack/plugins/apm/server/utils/test_helpers.tsx @@ -12,6 +12,7 @@ import { ESSearchResponse, } from '../../../../../src/core/types/elasticsearch'; import { UxUIFilters } from '../../typings/ui_filters'; +import { ApmIndicesConfig } from '../lib/settings/apm_indices/get_apm_indices'; interface Options { mockResponse?: ( @@ -26,18 +27,7 @@ interface MockSetup { internalClient: any; config: APMConfig; uiFilters: UxUIFilters; - indices: { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': string; - 'apm_oss.errorIndices': string; - 'apm_oss.onboardingIndices': string; - 'apm_oss.spanIndices': string; - 'apm_oss.transactionIndices': string; - 'apm_oss.metricsIndices': string; - /* eslint-enable @typescript-eslint/naming-convention */ - apmAgentConfigurationIndex: string; - apmCustomLinkIndex: string; - }; + indices: ApmIndicesConfig; } export async function inspectSearchParams( @@ -61,6 +51,16 @@ export async function inspectSearchParams( let response; let error; + const mockApmIndices: { + [Property in keyof APMConfig['indices']]: string; + } = { + sourcemap: 'myIndex', + error: 'myIndex', + onboarding: 'myIndex', + span: 'myIndex', + transaction: 'myIndex', + metric: 'myIndex', + }; const mockSetup = { apmEventClient: { search: spy } as any, internalClient: { search: spy } as any, @@ -76,8 +76,15 @@ export async function inspectSearchParams( switch (key) { default: return 'myIndex'; - - case 'xpack.apm.metricsInterval': + case 'indices': + return mockApmIndices; + case 'ui': + return { + enabled: true, + transactionGroupBucketSize: 1000, + maxTraceItems: 1000, + }; + case 'metricsInterval': return 30; } }, @@ -85,14 +92,7 @@ export async function inspectSearchParams( ) as APMConfig, uiFilters: options?.uiFilters ?? {}, indices: { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': 'myIndex', - 'apm_oss.errorIndices': 'myIndex', - 'apm_oss.onboardingIndices': 'myIndex', - 'apm_oss.spanIndices': 'myIndex', - 'apm_oss.transactionIndices': 'myIndex', - 'apm_oss.metricsIndices': 'myIndex', - /* eslint-enable @typescript-eslint/naming-convention */ + ...mockApmIndices, apmAgentConfigurationIndex: 'myIndex', apmCustomLinkIndex: 'myIndex', }, diff --git a/x-pack/plugins/apm/tsconfig.json b/x-pack/plugins/apm/tsconfig.json index c1030d2a4be1d..5db20725dd785 100644 --- a/x-pack/plugins/apm/tsconfig.json +++ b/x-pack/plugins/apm/tsconfig.json @@ -19,7 +19,6 @@ ], "references": [ { "path": "../../../src/core/tsconfig.json" }, - { "path": "../../../src/plugins/apm_oss/tsconfig.json" }, { "path": "../../../src/plugins/data/tsconfig.json" }, { "path": "../../../src/plugins/embeddable/tsconfig.json" }, { "path": "../../../src/plugins/home/tsconfig.json" }, diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset_manager.stories.storyshot b/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset_manager.stories.storyshot index 6ef6d19e446db..45b9d896db5f2 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset_manager.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset_manager.stories.storyshot @@ -54,7 +54,7 @@ exports[`Storyshots components/Assets/AssetManager no assets 1`] = ` > <input accept="image/*" - aria-describedby="generated-id" + aria-describedby="generated-id-filePicker__prompt" className="euiFilePicker__input" multiple={true} onChange={[Function]} @@ -65,7 +65,7 @@ exports[`Storyshots components/Assets/AssetManager no assets 1`] = ` /> <div className="euiFilePicker__prompt" - id="generated-id" + id="generated-id-filePicker__prompt" > <span aria-hidden="true" @@ -238,7 +238,7 @@ exports[`Storyshots components/Assets/AssetManager two assets 1`] = ` > <input accept="image/*" - aria-describedby="generated-id" + aria-describedby="generated-id-filePicker__prompt" className="euiFilePicker__input" multiple={true} onChange={[Function]} @@ -249,7 +249,7 @@ exports[`Storyshots components/Assets/AssetManager two assets 1`] = ` /> <div className="euiFilePicker__prompt" - id="generated-id" + id="generated-id-filePicker__prompt" > <span aria-hidden="true" diff --git a/x-pack/plugins/canvas/public/components/expression_input/__stories__/__snapshots__/expression_input.stories.storyshot b/x-pack/plugins/canvas/public/components/expression_input/__stories__/__snapshots__/expression_input.stories.storyshot index 9c9ed566e9482..bfd08e4ab823e 100644 --- a/x-pack/plugins/canvas/public/components/expression_input/__stories__/__snapshots__/expression_input.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/expression_input/__stories__/__snapshots__/expression_input.stories.storyshot @@ -29,7 +29,7 @@ exports[`Storyshots components/ExpressionInput default 1`] = ` aria-label="Code Editor" className="kibanaCodeEditor__keyboardHint" data-test-subj="codeEditorHint" - id="generated-id" + id="codeEditor_generated-id" onBlur={[Function]} onClick={[Function]} onFocus={[Function]} diff --git a/x-pack/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.stories.storyshot b/x-pack/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.stories.storyshot index 5fe43c95d271d..ab76e9a66a2b5 100644 --- a/x-pack/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.stories.storyshot @@ -8,7 +8,7 @@ exports[`Storyshots components/FileUpload default 1`] = ` className="euiFilePicker__wrap" > <input - aria-describedby="generated-id" + aria-describedby="generated-id-filePicker__prompt" className="euiFilePicker__input" id="" onChange={[Function]} @@ -19,7 +19,7 @@ exports[`Storyshots components/FileUpload default 1`] = ` /> <div className="euiFilePicker__prompt" - id="generated-id" + id="generated-id-filePicker__prompt" > <span aria-hidden="true" diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/__snapshots__/workpad_table.stories.storyshot b/x-pack/plugins/canvas/public/components/home/my_workpads/__snapshots__/workpad_table.stories.storyshot index 7d05176b8147c..f955a6e2322a9 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/__snapshots__/workpad_table.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/__snapshots__/workpad_table.stories.storyshot @@ -54,7 +54,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` > <input accept="application/json" - aria-describedby="generated-id" + aria-describedby="generated-id-filePicker__prompt" aria-label="Import workpad JSON file" className="euiFilePicker__input" disabled={false} @@ -66,7 +66,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` /> <div className="euiFilePicker__prompt" - id="generated-id" + id="generated-id-filePicker__prompt" > <span aria-hidden="true" @@ -109,7 +109,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` checked={false} className="euiCheckbox__input" disabled={false} - id="_selection_column-checkbox_generated-id" + id="_selection_column-checkbox_generated-id_mobile" onChange={[Function]} type="checkbox" /> @@ -118,7 +118,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` /> <label className="euiCheckbox__label" - htmlFor="_selection_column-checkbox_generated-id" + htmlFor="_selection_column-checkbox_generated-id_mobile" > Select all rows </label> @@ -166,7 +166,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` </div> <table className="euiTable euiTable--responsive" - id="generated-id" + id="__table_generated-id" tabIndex={-1} > <caption @@ -195,7 +195,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` className="euiCheckbox__input" data-test-subj="checkboxSelectAll" disabled={false} - id="_selection_column-checkbox_generated-id" + id="_selection_column-checkbox_generated-id_desktop" onChange={[Function]} type="checkbox" /> @@ -921,7 +921,7 @@ exports[`Storyshots Home/Components/Workpad Table Workpad Table 1`] = ` className="euiPagination__item" > <button - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-current={true} aria-label="Page 1 of 1" className="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiButtonEmpty-isDisabled euiPaginationButton euiPaginationButton-isActive euiPaginationButton--hideOnMobile" diff --git a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss index 3f6d6887e0c80..4acdca10d61cc 100644 --- a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss +++ b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss @@ -31,7 +31,7 @@ $canvasLayoutFontSize: $euiFontSizeS; .canvasLayout__stageHeader { flex-grow: 0; flex-basis: auto; - padding: 1px $euiSize 0; + padding: $euiSizeS; font-size: $canvasLayoutFontSize; border-bottom: $euiBorderThin; background: $euiColorLightestShade; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/__snapshots__/element_menu.stories.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/__snapshots__/element_menu.stories.storyshot index 371a5133fe88e..1e71803d22c21 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/__snapshots__/element_menu.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/__snapshots__/element_menu.stories.storyshot @@ -3,13 +3,13 @@ exports[`Storyshots components/WorkpadHeader/ElementMenu default 1`] = ` <div className="euiPopover euiPopover--anchorDownLeft" + data-test-subj="add-element-button" > <div className="euiPopover__anchor" > <button - aria-label="Add an element" - className="euiButton euiButton--primary euiButton--small euiButton--fill canvasElementMenu__popoverButton" + className="euiButton euiButton--primary euiButton--fill solutionToolbarButton undefined" data-test-subj="add-element-button" disabled={false} onClick={[Function]} diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx index 80280d55a4e1c..9d37873bcae0a 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx @@ -129,12 +129,6 @@ You can use standard Markdown in here, but you can also access your piped-in dat }, }; -const mockRenderEmbedPanel = () => <div id="embeddablePanel" />; - storiesOf('components/WorkpadHeader/ElementMenu', module).add('default', () => ( - <ElementMenu - elements={testElements} - addElement={action('addElement')} - renderEmbedPanel={mockRenderEmbedPanel} - /> + <ElementMenu elements={testElements} addElement={action('addElement')} /> )); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx index 937912570b77f..8ac581b0866a4 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx @@ -6,17 +6,13 @@ */ import { sortBy } from 'lodash'; -import React, { Fragment, FunctionComponent, useState } from 'react'; +import React, { FunctionComponent, useState } from 'react'; import PropTypes from 'prop-types'; -import { - EuiButton, - EuiContextMenu, - EuiIcon, - EuiContextMenuPanelItemDescriptor, -} from '@elastic/eui'; +import { EuiContextMenu, EuiIcon, EuiContextMenuPanelItemDescriptor } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { PrimaryActionPopover } from '../../../../../../../src/plugins/presentation_util/public'; import { getId } from '../../../lib/get_id'; -import { Popover, ClosePopoverFn } from '../../popover'; +import { ClosePopoverFn } from '../../popover'; import { CONTEXT_MENU_TOP_BORDER_CLASSNAME } from '../../../../common/lib'; import { ElementSpec } from '../../../../types'; import { flattenPanelTree } from '../../../lib/flatten_panel_tree'; @@ -116,7 +112,7 @@ const categorizeElementsByType = (elements: ElementSpec[]): { [key: string]: Ele return categories; }; -export interface Props { +interface Props { /** * Dictionary of elements from elements registry */ @@ -125,25 +121,14 @@ export interface Props { * Handler for adding a selected element to the workpad */ addElement: (element: ElementSpec) => void; - /** - * Renders embeddable flyout - */ - renderEmbedPanel: (onClose: () => void) => JSX.Element; } -export const ElementMenu: FunctionComponent<Props> = ({ - elements, - addElement, - renderEmbedPanel, -}) => { +export const ElementMenu: FunctionComponent<Props> = ({ elements, addElement }) => { const [isAssetModalVisible, setAssetModalVisible] = useState(false); - const [isEmbedPanelVisible, setEmbedPanelVisible] = useState(false); const [isSavedElementsModalVisible, setSavedElementsModalVisible] = useState(false); const hideAssetModal = () => setAssetModalVisible(false); const showAssetModal = () => setAssetModalVisible(true); - const hideEmbedPanel = () => setEmbedPanelVisible(false); - const showEmbedPanel = () => setEmbedPanelVisible(true); const hideSavedElementsModal = () => setSavedElementsModalVisible(false); const showSavedElementsModal = () => setSavedElementsModalVisible(true); @@ -214,47 +199,28 @@ export const ElementMenu: FunctionComponent<Props> = ({ closePopover(); }, }, - { - name: strings.getEmbedObjectMenuItemLabel(), - className: CONTEXT_MENU_TOP_BORDER_CLASSNAME, - icon: <EuiIcon type="logoKibana" size="m" />, - onClick: () => { - showEmbedPanel(); - closePopover(); - }, - }, ], }; }; - const exportControl = (togglePopover: React.MouseEventHandler<any>) => ( - <EuiButton - fill - iconType="plusInCircle" - size="s" - aria-label={strings.getElementMenuLabel()} - onClick={togglePopover} - className="canvasElementMenu__popoverButton" - data-test-subj="add-element-button" - > - {strings.getElementMenuButtonLabel()} - </EuiButton> - ); - return ( - <Fragment> - <Popover button={exportControl} panelPaddingSize="none" anchorPosition="downLeft"> + <> + <PrimaryActionPopover + panelPaddingSize="none" + label={strings.getElementMenuButtonLabel()} + iconType="plusInCircle" + data-test-subj="add-element-button" + > {({ closePopover }: { closePopover: ClosePopoverFn }) => ( <EuiContextMenu initialPanelId={0} panels={flattenPanelTree(getPanelTree(closePopover))} /> )} - </Popover> + </PrimaryActionPopover> {isAssetModalVisible ? <AssetManager onClose={hideAssetModal} /> : null} - {isEmbedPanelVisible ? renderEmbedPanel(hideEmbedPanel) : null} {isSavedElementsModalVisible ? <SavedElementsModal onClose={hideSavedElementsModal} /> : null} - </Fragment> + </> ); }; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.scss b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.scss deleted file mode 100644 index a946ee5519ce4..0000000000000 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.scss +++ /dev/null @@ -1,3 +0,0 @@ -.canvasElementMenu__popoverButton { - margin-right: $euiSizeS; -} \ No newline at end of file diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.tsx index 5b5491a7c6454..d43d13a65a5d7 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.tsx @@ -5,44 +5,4 @@ * 2.0. */ -import React from 'react'; -import { connect } from 'react-redux'; -import { compose, withProps } from 'recompose'; -import { Dispatch } from 'redux'; -import { State, ElementSpec } from '../../../../types'; -// @ts-expect-error untyped local -import { elementsRegistry } from '../../../lib/elements_registry'; -import { ElementMenu as Component, Props as ComponentProps } from './element_menu.component'; -// @ts-expect-error untyped local -import { addElement } from '../../../state/actions/elements'; -import { getSelectedPage } from '../../../state/selectors/workpad'; -import { AddEmbeddablePanel } from '../../embeddable_flyout'; - -interface StateProps { - pageId: string; -} - -interface DispatchProps { - addElement: (pageId: string) => (partialElement: ElementSpec) => void; -} - -const mapStateToProps = (state: State) => ({ - pageId: getSelectedPage(state), -}); - -const mapDispatchToProps = (dispatch: Dispatch) => ({ - addElement: (pageId: string) => (element: ElementSpec) => dispatch(addElement(pageId, element)), -}); - -const mergeProps = (stateProps: StateProps, dispatchProps: DispatchProps) => ({ - ...stateProps, - ...dispatchProps, - addElement: dispatchProps.addElement(stateProps.pageId), - // Moved this section out of the main component to enable stories - renderEmbedPanel: (onClose: () => void) => <AddEmbeddablePanel onClose={onClose} />, -}); - -export const ElementMenu = compose<ComponentProps, {}>( - connect(mapStateToProps, mapDispatchToProps, mergeProps), - withProps(() => ({ elements: elementsRegistry.toJS() })) -)(Component); +export * from './element_menu.component'; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx index 5320a65a90408..f031d7c263199 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx @@ -5,13 +5,19 @@ * 2.0. */ -import React, { FunctionComponent } from 'react'; +import React, { FC, useCallback, useState } from 'react'; import PropTypes from 'prop-types'; // @ts-expect-error no @types definition import { Shortcuts } from 'react-shortcuts'; import { EuiFlexItem, EuiFlexGroup, EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; - +import { + AddFromLibraryButton, + QuickButtonGroup, + SolutionToolbar, +} from '../../../../../../src/plugins/presentation_util/public'; +import { getElementStrings } from '../../../i18n'; +import { CommitFn, ElementSpec } from '../../../types'; import { ToolTipShortcut } from '../tool_tip_shortcut/'; import { RefreshControl } from './refresh_control'; // @ts-expect-error untyped local @@ -21,7 +27,6 @@ import { ElementMenu } from './element_menu'; import { ShareMenu } from './share_menu'; import { ViewMenu } from './view_menu'; import { LabsControl } from './labs_control'; -import { CommitFn } from '../../../types'; const strings = { getFullScreenButtonAriaLabel: () => @@ -46,19 +51,30 @@ const strings = { }), }; +const elementStrings = getElementStrings(); + export interface Props { isWriteable: boolean; canUserWrite: boolean; commit: CommitFn; onSetWriteable?: (writeable: boolean) => void; + renderEmbedPanel: (onClick: () => void) => JSX.Element; + elements: { [key: string]: ElementSpec }; + addElement: (element: Partial<ElementSpec>) => void; } -export const WorkpadHeader: FunctionComponent<Props> = ({ +export const WorkpadHeader: FC<Props> = ({ isWriteable, canUserWrite, commit, onSetWriteable = () => {}, + renderEmbedPanel, + elements, + addElement, }) => { + const [isEmbedPanelVisible, setEmbedPanelVisible] = useState(false); + const hideEmbedPanel = () => setEmbedPanelVisible(false); + const showEmbedPanel = () => setEmbedPanelVisible(true); const toggleWriteable = () => onSetWriteable(!isWriteable); const keyHandler = (action: string) => { @@ -111,65 +127,104 @@ export const WorkpadHeader: FunctionComponent<Props> = ({ ); }; + const createElement = useCallback( + (elementName: string) => () => { + const elementSpec = elements[elementName]; + if (elementSpec) { + addElement(elements[elementName]); + } + }, + [addElement, elements] + ); + + const quickButtons = [ + { + iconType: 'visText', + createType: elementStrings.markdown.displayName, + onClick: createElement('markdown'), + }, + { + iconType: 'node', + createType: elementStrings.shape.displayName, + onClick: createElement('shape'), + }, + { + iconType: 'image', + createType: elementStrings.image.displayName, + onClick: createElement('image'), + }, + ]; + return ( - <EuiFlexGroup - gutterSize="none" - alignItems="center" - justifyContent="spaceBetween" - className="canvasLayout__stageHeaderInner" - > - <EuiFlexItem grow={false}> - <EuiFlexGroup alignItems="center" gutterSize="none"> - {isWriteable && ( + <> + <EuiFlexGroup + gutterSize="none" + alignItems="center" + justifyContent="spaceBetween" + className="canvasLayout__stageHeaderInner" + > + <EuiFlexItem grow={false}> + <EuiFlexGroup alignItems="center" gutterSize="none"> + {isWriteable && ( + <EuiFlexItem> + <SolutionToolbar> + {{ + primaryActionButton: ( + <ElementMenu addElement={addElement} elements={elements} /> + ), + quickButtonGroup: <QuickButtonGroup buttons={quickButtons} />, + addFromLibraryButton: <AddFromLibraryButton onClick={showEmbedPanel} />, + }} + </SolutionToolbar> + </EuiFlexItem> + )} <EuiFlexItem grow={false}> - <ElementMenu /> + <ViewMenu /> </EuiFlexItem> - )} - <EuiFlexItem grow={false}> - <ViewMenu /> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <EditMenu commit={commit} /> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <ShareMenu /> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <LabsControl /> - </EuiFlexItem> - </EuiFlexGroup> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <EuiFlexGroup alignItems="center" gutterSize="s"> - <EuiFlexItem grow={false}> - {canUserWrite && ( - <Shortcuts - name="EDITOR" - handler={keyHandler} - targetNodeSelector="body" - global - isolate - /> - )} - <EuiToolTip position="bottom" content={getEditToggleToolTip()}> - <EuiButtonIcon - iconType={isWriteable ? 'eyeClosed' : 'eye'} - onClick={toggleWriteable} - size="s" - aria-label={getEditToggleToolTipText()} - isDisabled={!canUserWrite} - /> - </EuiToolTip> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <RefreshControl /> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <FullscreenControl>{fullscreenButton}</FullscreenControl> - </EuiFlexItem> - </EuiFlexGroup> - </EuiFlexItem> - </EuiFlexGroup> + <EuiFlexItem grow={false}> + <EditMenu commit={commit} /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <ShareMenu /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <LabsControl /> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiFlexGroup alignItems="center" gutterSize="s"> + <EuiFlexItem grow={false}> + {canUserWrite && ( + <Shortcuts + name="EDITOR" + handler={keyHandler} + targetNodeSelector="body" + global + isolate + /> + )} + <EuiToolTip position="bottom" content={getEditToggleToolTip()}> + <EuiButtonIcon + iconType={isWriteable ? 'eyeClosed' : 'eye'} + onClick={toggleWriteable} + size="s" + aria-label={getEditToggleToolTipText()} + isDisabled={!canUserWrite} + /> + </EuiToolTip> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <RefreshControl /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <FullscreenControl>{fullscreenButton}</FullscreenControl> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFlexItem> + </EuiFlexGroup> + {isEmbedPanelVisible ? renderEmbedPanel(hideEmbedPanel) : null} + </> ); }; @@ -178,4 +233,7 @@ WorkpadHeader.propTypes = { commit: PropTypes.func.isRequired, onSetWriteable: PropTypes.func, canUserWrite: PropTypes.bool, + renderEmbedPanel: PropTypes.func.isRequired, + elements: PropTypes.object.isRequired, + addElement: PropTypes.func.isRequired, }; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx index 0521df0f09196..e5702f9be2a13 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx @@ -5,22 +5,61 @@ * 2.0. */ +import React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; +import { Action } from 'redux-actions'; +// @ts-expect-error untyped local +import { elementsRegistry } from '../../lib/elements_registry'; import { canUserWrite } from '../../state/selectors/app'; import { getSelectedPage, isWriteable } from '../../state/selectors/workpad'; import { setWriteable } from '../../state/actions/workpad'; -import { State } from '../../../types'; -import { WorkpadHeader as Component } from './workpad_header.component'; +// @ts-expect-error untyped local +import { addElement } from '../../state/actions/elements'; +import { CommitFn, ElementSpec, State } from '../../../types'; +import { WorkpadHeader as Component, Props as ComponentProps } from './workpad_header.component'; +import { AddEmbeddablePanel } from '../embeddable_flyout'; -const mapStateToProps = (state: State) => ({ +interface Props { + commit: CommitFn; +} + +interface StateProps { + isWriteable: boolean; + canUserWrite: boolean; + selectedPage: string; + pageId: string; +} + +interface DispatchProps { + onSetWriteable: (isWorkpadWriteable: boolean) => Action<boolean>; + addElement: (pageId: string) => (partialElement: Partial<ElementSpec>) => void; +} + +const mapStateToProps = (state: State): StateProps => ({ isWriteable: isWriteable(state) && canUserWrite(state), canUserWrite: canUserWrite(state), selectedPage: getSelectedPage(state), + pageId: getSelectedPage(state), }); -const mapDispatchToProps = (dispatch: Dispatch) => ({ +const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({ onSetWriteable: (isWorkpadWriteable: boolean) => dispatch(setWriteable(isWorkpadWriteable)), + addElement: (pageId: string) => (element: Partial<ElementSpec>) => + dispatch(addElement(pageId, element)), +}); + +const mergeProps = ( + stateProps: StateProps, + dispatchProps: DispatchProps, + ownProps: Props +): ComponentProps => ({ + ...stateProps, + ...dispatchProps, + ...ownProps, + renderEmbedPanel: (onClose: () => void) => <AddEmbeddablePanel onClose={onClose} />, + addElement: dispatchProps.addElement(stateProps.pageId), + elements: elementsRegistry.toJS(), }); -export const WorkpadHeader = connect(mapStateToProps, mapDispatchToProps)(Component); +export const WorkpadHeader = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component); diff --git a/x-pack/plugins/canvas/public/style/index.scss b/x-pack/plugins/canvas/public/style/index.scss index 0860bfd5afe6a..e03405f6226c7 100644 --- a/x-pack/plugins/canvas/public/style/index.scss +++ b/x-pack/plugins/canvas/public/style/index.scss @@ -36,7 +36,6 @@ @import '../components/toolbar/toolbar'; @import '../components/toolbar/tray/tray'; @import '../components/workpad/workpad'; -@import '../components/workpad_header/element_menu/element_menu'; @import '../components/workpad_header/share_menu/share_menu'; @import '../components/workpad_header/view_menu/view_menu'; @import '../components/workpad_page/workpad_page'; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx index 23d4dbbe62a8f..8be457b956be6 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx @@ -21,11 +21,7 @@ import { Settings } from './settings'; jest.mock('../../../supported_renderers'); jest.mock(`@elastic/eui/lib/components/form/form_row/make_id`, () => () => `generated-id`); -jest.mock('@elastic/eui/lib/services/accessibility', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); + jest.mock('@elastic/eui/lib/components/portal/portal', () => { // eslint-disable-next-line @typescript-eslint/no-shadow const React = jest.requireActual('react'); diff --git a/x-pack/plugins/canvas/storybook/storyshots.test.tsx b/x-pack/plugins/canvas/storybook/storyshots.test.tsx index f99a1ed5d4335..8a55c6f12bf51 100644 --- a/x-pack/plugins/canvas/storybook/storyshots.test.tsx +++ b/x-pack/plugins/canvas/storybook/storyshots.test.tsx @@ -51,13 +51,6 @@ jest.mock('@elastic/eui/packages/react-datepicker', () => { // @ts-expect-error Portal mocks are notoriously difficult to type ReactDOM.createPortal = jest.fn((element) => element); -// Mock the EUI HTML ID Generator so elements have a predictable ID in snapshots -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - // To be resolved by EUI team. // https://github.com/elastic/eui/issues/3712 jest.mock('@elastic/eui/lib/components/overlay_mask/overlay_mask', () => { diff --git a/x-pack/plugins/canvas/tsconfig.json b/x-pack/plugins/canvas/tsconfig.json index 5e3c7a7299adb..5064bac975a9c 100644 --- a/x-pack/plugins/canvas/tsconfig.json +++ b/x-pack/plugins/canvas/tsconfig.json @@ -42,6 +42,7 @@ { "path": "../../../src/plugins/kibana_legacy/tsconfig.json" }, { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, + { "path": "../../../src/plugins/presentation_util/tsconfig.json" }, { "path": "../../../src/plugins/saved_objects/tsconfig.json" }, { "path": "../../../src/plugins/ui_actions/tsconfig.json" }, { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, diff --git a/x-pack/plugins/cases/README.md b/x-pack/plugins/cases/README.md index f894ca23dfbf0..f28926eb52052 100644 --- a/x-pack/plugins/cases/README.md +++ b/x-pack/plugins/cases/README.md @@ -1,9 +1,9 @@ -Case management in Kibana +# Case management in Kibana [![Issues][issues-shield]][issues-url] -[![Pull Requests][pr-shield]][pr-url] +[![Pull Requests][pr-shield]][pr-url] -# Cases Plugin Docs +# Docs ![Cases Logo][cases-logo] @@ -288,9 +288,9 @@ Connectors of type (`.none`) should have the `fields` attribute set to `null`. <!-- MARKDOWN LINKS & IMAGES --> <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --> -[pr-shield]: https://img.shields.io/github/issues-pr/elangosundar/awesome-README-templates?style=for-the-badge -[pr-url]: https://github.com/elastic/kibana/pulls?q=is%3Apr+label%3AFeature%3ACases+-is%3Adraft+is%3Aopen+ -[issues-shield]: https://img.shields.io/github/issues/othneildrew/Best-README-Template.svg?style=for-the-badge +[pr-shield]: https://img.shields.io/github/issues-pr/elastic/kibana/Team:Threat%20Hunting:Cases?label=pull%20requests&style=for-the-badge +[pr-url]: https://github.com/elastic/kibana/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc+label%3A%22Team%3AThreat+Hunting%3ACases%22 +[issues-shield]: https://img.shields.io/github/issues-search?label=issue&query=repo%3Aelastic%2Fkibana%20is%3Aissue%20is%3Aopen%20label%3A%22Team%3AThreat%20Hunting%3ACases%22&style=for-the-badge [issues-url]: https://github.com/elastic/kibana/issues?q=is%3Aopen+is%3Aissue+label%3AFeature%3ACases [cases-logo]: images/logo.png [configure-img]: images/configure.png diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts index 948b203af14a8..b4ed4f7db177e 100644 --- a/x-pack/plugins/cases/common/ui/types.ts +++ b/x-pack/plugins/cases/common/ui/types.ts @@ -16,6 +16,7 @@ import { User, UserAction, UserActionField, + ActionConnector, } from '../api'; export interface CasesUiConfigType { @@ -259,3 +260,5 @@ export interface Ecs { _index?: string; signal?: SignalEcs; } + +export type CaseActionConnector = ActionConnector; diff --git a/x-pack/plugins/cases/public/common/mock/register_connectors.ts b/x-pack/plugins/cases/public/common/mock/register_connectors.ts new file mode 100644 index 0000000000000..42e7cd4a85e40 --- /dev/null +++ b/x-pack/plugins/cases/public/common/mock/register_connectors.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TriggersAndActionsUIPublicPluginStart } from '../../../../triggers_actions_ui/public'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; +import { CaseActionConnector } from '../../../common'; + +const getUniqueActionTypeIds = (connectors: CaseActionConnector[]) => + new Set(connectors.map((connector) => connector.actionTypeId)); + +export const registerConnectorsToMockActionRegistry = ( + actionTypeRegistry: TriggersAndActionsUIPublicPluginStart['actionTypeRegistry'], + connectors: CaseActionConnector[] +) => { + const { createMockActionTypeModel } = actionTypeRegistryMock; + const uniqueActionTypeIds = getUniqueActionTypeIds(connectors); + uniqueActionTypeIds.forEach((actionTypeId) => + actionTypeRegistry.register( + createMockActionTypeModel({ id: actionTypeId, iconClass: 'logoSecurity' }) + ) + ); +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx index 0e548fd53c89d..fed23564a3955 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx @@ -19,8 +19,8 @@ import { useKibana } from '../../common/lib/kibana'; import { StatusAll } from '../../containers/types'; import { CaseStatuses, SECURITY_SOLUTION_OWNER } from '../../../common'; import { connectorsMock } from '../../containers/mock'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; import { triggersActionsUiMock } from '../../../../triggers_actions_ui/public/mocks'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; jest.mock('../../containers/use_get_reporters'); jest.mock('../../containers/use_get_tags'); @@ -59,14 +59,10 @@ jest.mock('../../common/lib/kibana', () => { }); describe('AllCasesGeneric ', () => { - const { createMockActionTypeModel } = actionTypeRegistryMock; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; beforeAll(() => { - connectorsMock.forEach((connector) => - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.register( - createMockActionTypeModel({ id: connector.actionTypeId, iconClass: 'logoSecurity' }) - ) - ); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectorsMock); }); beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx b/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx index 015ba877a2749..090ac0d31ed06 100644 --- a/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx @@ -12,21 +12,17 @@ import '../../common/mock/match_media'; import { ExternalServiceColumn } from './columns'; import { useGetCasesMockState } from '../../containers/mock'; import { useKibana } from '../../common/lib/kibana'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; import { connectors } from '../configure_cases/__mock__'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; jest.mock('../../common/lib/kibana'); const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>; describe('ExternalServiceColumn ', () => { - const { createMockActionTypeModel } = actionTypeRegistryMock; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; beforeAll(() => { - connectors.forEach((connector) => - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.register( - createMockActionTypeModel({ id: connector.actionTypeId, iconClass: 'logoSecurity' }) - ) - ); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectors); }); it('Not pushed render', () => { diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index 3fff43108772d..a387c5eae3834 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -32,8 +32,8 @@ import { useKibana } from '../../common/lib/kibana'; import { AllCasesGeneric as AllCases } from './all_cases_generic'; import { AllCasesProps } from '.'; import { CasesColumns, GetCasesColumn, useCasesColumns } from './columns'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; import { triggersActionsUiMock } from '../../../../triggers_actions_ui/public/mocks'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; jest.mock('../../containers/use_bulk_update_case'); jest.mock('../../containers/use_delete_cases'); @@ -148,14 +148,10 @@ describe('AllCasesGeneric', () => { userCanCrud: true, }; - const { createMockActionTypeModel } = actionTypeRegistryMock; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; beforeAll(() => { - connectorsMock.forEach((connector) => - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.register( - createMockActionTypeModel({ id: connector.actionTypeId, iconClass: 'logoSecurity' }) - ) - ); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectorsMock); }); beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx index 0bda6fe185093..38923784d862c 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; +import { render, screen } from '@testing-library/react'; import { Connectors, Props } from './connectors'; import { TestProviders } from '../../common/mock'; @@ -14,6 +15,7 @@ import { ConnectorsDropdown } from './connectors_dropdown'; import { connectors, actionTypes } from './__mock__'; import { ConnectorTypes } from '../../../common'; import { useKibana } from '../../common/lib/kibana'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; jest.mock('../../common/lib/kibana'); const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>; @@ -35,11 +37,10 @@ describe('Connectors', () => { updateConnectorDisabled: false, }; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; + beforeAll(() => { - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ - actionTypeTitle: 'test', - iconClass: 'logoSecurity', - }); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectors); wrapper = mount(<Connectors {...props} />, { wrappingComponent: TestProviders }); }); @@ -121,4 +122,33 @@ describe('Connectors', () => { .text() ).toBe('Update My Connector'); }); + + test('it shows the deprecated callout when the connector is legacy', async () => { + render( + <Connectors + {...props} + selectedConnector={{ id: 'servicenow-legacy', type: ConnectorTypes.serviceNowITSM }} + />, + { + // wrapper: TestProviders produces a TS error + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } + ); + + expect(screen.getByText('Deprecated connector type')).toBeInTheDocument(); + expect( + screen.getByText( + 'This connector type is deprecated. Create a new connector or update this connector' + ) + ).toBeInTheDocument(); + }); + + test('it does not shows the deprecated callout when the connector is none', async () => { + render(<Connectors {...props} />, { + // wrapper: TestProviders produces a TS error + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(screen.queryByText('Deprecated connector type')).not.toBeInTheDocument(); + }); }); diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx index 40f314a653882..1b575e3ba9334 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx @@ -22,6 +22,8 @@ import * as i18n from './translations'; import { ActionConnector, CaseConnectorMapping } from '../../containers/configure/types'; import { Mapping } from './mapping'; import { ActionTypeConnector, ConnectorTypes } from '../../../common'; +import { DeprecatedCallout } from '../connectors/deprecated_callout'; +import { isLegacyConnector } from '../utils'; const EuiFormRowExtended = styled(EuiFormRow)` .euiFormRow__labelWrapper { @@ -53,11 +55,13 @@ const ConnectorsComponent: React.FC<Props> = ({ selectedConnector, updateConnectorDisabled, }) => { - const connectorsName = useMemo( - () => connectors.find((c) => c.id === selectedConnector.id)?.name ?? 'none', + const connector = useMemo( + () => connectors.find((c) => c.id === selectedConnector.id), [connectors, selectedConnector.id] ); + const connectorsName = connector?.name ?? 'none'; + const actionTypeName = useMemo( () => actionTypes.find((c) => c.id === selectedConnector.type)?.name ?? 'Unknown', [actionTypes, selectedConnector.type] @@ -107,6 +111,11 @@ const ConnectorsComponent: React.FC<Props> = ({ appendAddConnectorButton={true} /> </EuiFlexItem> + {selectedConnector.type !== ConnectorTypes.none && isLegacyConnector(connector) && ( + <EuiFlexItem grow={false}> + <DeprecatedCallout /> + </EuiFlexItem> + )} {selectedConnector.type !== ConnectorTypes.none ? ( <EuiFlexItem grow={false}> <Mapping diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx index 8eae574776e2e..34422392b7efa 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx @@ -8,12 +8,13 @@ import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; import { EuiSuperSelect } from '@elastic/eui'; +import { render, screen } from '@testing-library/react'; import { ConnectorsDropdown, Props } from './connectors_dropdown'; import { TestProviders } from '../../common/mock'; import { connectors } from './__mock__'; import { useKibana } from '../../common/lib/kibana'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; jest.mock('../../common/lib/kibana'); const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>; @@ -28,14 +29,10 @@ describe('ConnectorsDropdown', () => { selectedConnector: 'none', }; - const { createMockActionTypeModel } = actionTypeRegistryMock; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; beforeAll(() => { - connectors.forEach((connector) => - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.register( - createMockActionTypeModel({ id: connector.actionTypeId, iconClass: 'logoSecurity' }) - ) - ); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectors); wrapper = mount(<ConnectorsDropdown {...props} />, { wrappingComponent: TestProviders }); }); @@ -77,7 +74,7 @@ describe('ConnectorsDropdown', () => { "data-test-subj": "dropdown-connector-servicenow-1", "inputDisplay": <EuiFlexGroup alignItems="center" - gutterSize="none" + gutterSize="s" responsive={false} > <EuiFlexItem @@ -88,7 +85,9 @@ describe('ConnectorsDropdown', () => { type="logoSecurity" /> </EuiFlexItem> - <EuiFlexItem> + <EuiFlexItem + grow={false} + > <span> My Connector </span> @@ -100,7 +99,7 @@ describe('ConnectorsDropdown', () => { "data-test-subj": "dropdown-connector-resilient-2", "inputDisplay": <EuiFlexGroup alignItems="center" - gutterSize="none" + gutterSize="s" responsive={false} > <EuiFlexItem @@ -111,7 +110,9 @@ describe('ConnectorsDropdown', () => { type="logoSecurity" /> </EuiFlexItem> - <EuiFlexItem> + <EuiFlexItem + grow={false} + > <span> My Connector 2 </span> @@ -123,7 +124,7 @@ describe('ConnectorsDropdown', () => { "data-test-subj": "dropdown-connector-jira-1", "inputDisplay": <EuiFlexGroup alignItems="center" - gutterSize="none" + gutterSize="s" responsive={false} > <EuiFlexItem @@ -134,7 +135,9 @@ describe('ConnectorsDropdown', () => { type="logoSecurity" /> </EuiFlexItem> - <EuiFlexItem> + <EuiFlexItem + grow={false} + > <span> Jira </span> @@ -146,7 +149,7 @@ describe('ConnectorsDropdown', () => { "data-test-subj": "dropdown-connector-servicenow-sir", "inputDisplay": <EuiFlexGroup alignItems="center" - gutterSize="none" + gutterSize="s" responsive={false} > <EuiFlexItem @@ -157,7 +160,9 @@ describe('ConnectorsDropdown', () => { type="logoSecurity" /> </EuiFlexItem> - <EuiFlexItem> + <EuiFlexItem + grow={false} + > <span> My Connector SIR </span> @@ -165,6 +170,43 @@ describe('ConnectorsDropdown', () => { </EuiFlexGroup>, "value": "servicenow-sir", }, + Object { + "data-test-subj": "dropdown-connector-servicenow-legacy", + "inputDisplay": <EuiFlexGroup + alignItems="center" + gutterSize="s" + responsive={false} + > + <EuiFlexItem + grow={false} + > + <Styled(EuiIcon) + size="m" + type="logoSecurity" + /> + </EuiFlexItem> + <EuiFlexItem + grow={false} + > + <span> + My Connector + </span> + </EuiFlexItem> + <EuiFlexItem + grow={false} + > + <EuiIconTip + aria-label="Deprecated connector" + color="warning" + content="Please update your connector" + size="m" + title="Deprecated connector" + type="alert" + /> + </EuiFlexItem> + </EuiFlexGroup>, + "value": "servicenow-legacy", + }, ] `); }); @@ -245,4 +287,13 @@ describe('ConnectorsDropdown', () => { ) ).not.toThrowError(); }); + + test('it shows the deprecated tooltip when the connector is legacy', () => { + render(<ConnectorsDropdown {...props} selectedConnector="servicenow-legacy" />, { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + const tooltips = screen.getAllByLabelText('Deprecated connector'); + expect(tooltips[0]).toBeInTheDocument(); + }); }); diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx index 3cab2afd41f41..f21b3ab3d544f 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx @@ -6,14 +6,14 @@ */ import React, { useMemo } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSuperSelect } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiIconTip, EuiSuperSelect } from '@elastic/eui'; import styled from 'styled-components'; import { ConnectorTypes } from '../../../common'; import { ActionConnector } from '../../containers/configure/types'; import * as i18n from './translations'; import { useKibana } from '../../common/lib/kibana'; -import { getConnectorIcon } from '../utils'; +import { getConnectorIcon, isLegacyConnector } from '../utils'; export interface Props { connectors: ActionConnector[]; @@ -79,16 +79,28 @@ const ConnectorsDropdownComponent: React.FC<Props> = ({ { value: connector.id, inputDisplay: ( - <EuiFlexGroup gutterSize="none" alignItems="center" responsive={false}> + <EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}> <EuiFlexItem grow={false}> <EuiIconExtended type={getConnectorIcon(triggersActionsUi, connector.actionTypeId)} size={ICON_SIZE} /> </EuiFlexItem> - <EuiFlexItem> + <EuiFlexItem grow={false}> <span>{connector.name}</span> </EuiFlexItem> + {isLegacyConnector(connector) && ( + <EuiFlexItem grow={false}> + <EuiIconTip + aria-label={i18n.DEPRECATED_TOOLTIP_TITLE} + size={ICON_SIZE} + type="alert" + color="warning" + title={i18n.DEPRECATED_TOOLTIP_TITLE} + content={i18n.DEPRECATED_TOOLTIP_CONTENT} + /> + </EuiFlexItem> + )} </EuiFlexGroup> ), 'data-test-subj': `dropdown-connector-${connector.id}`, diff --git a/x-pack/plugins/cases/public/components/configure_cases/translations.ts b/x-pack/plugins/cases/public/components/configure_cases/translations.ts index 878d261369340..4a775c78d4ab8 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/translations.ts +++ b/x-pack/plugins/cases/public/components/configure_cases/translations.ts @@ -162,3 +162,17 @@ export const UPDATE_SELECTED_CONNECTOR = (connectorName: string): string => values: { connectorName }, defaultMessage: 'Update { connectorName }', }); + +export const DEPRECATED_TOOLTIP_TITLE = i18n.translate( + 'xpack.cases.configureCases.deprecatedTooltipTitle', + { + defaultMessage: 'Deprecated connector', + } +); + +export const DEPRECATED_TOOLTIP_CONTENT = i18n.translate( + 'xpack.cases.configureCases.deprecatedTooltipContent', + { + defaultMessage: 'Please update your connector', + } +); diff --git a/x-pack/plugins/cases/public/components/connectors/card.test.tsx b/x-pack/plugins/cases/public/components/connectors/card.test.tsx index b5d70a6781916..384442814ffef 100644 --- a/x-pack/plugins/cases/public/components/connectors/card.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/card.test.tsx @@ -10,22 +10,18 @@ import { mount } from 'enzyme'; import { ConnectorTypes } from '../../../common'; import { useKibana } from '../../common/lib/kibana'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; import { connectors } from '../configure_cases/__mock__'; import { ConnectorCard } from './card'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; jest.mock('../../common/lib/kibana'); const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>; describe('ConnectorCard ', () => { - const { createMockActionTypeModel } = actionTypeRegistryMock; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; beforeAll(() => { - connectors.forEach((connector) => - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.register( - createMockActionTypeModel({ id: connector.actionTypeId, iconClass: 'logoSecurity' }) - ) - ); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectors); }); it('it does not throw when accessing the icon if the connector type is not registered', () => { diff --git a/x-pack/plugins/cases/public/components/connectors/deprecated_callout.test.tsx b/x-pack/plugins/cases/public/components/connectors/deprecated_callout.test.tsx new file mode 100644 index 0000000000000..6b1475e3c4bd0 --- /dev/null +++ b/x-pack/plugins/cases/public/components/connectors/deprecated_callout.test.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DeprecatedCallout } from './deprecated_callout'; + +describe('DeprecatedCallout', () => { + test('it renders correctly', () => { + render(<DeprecatedCallout />); + expect(screen.getByText('Deprecated connector type')).toBeInTheDocument(); + expect( + screen.getByText( + 'This connector type is deprecated. Create a new connector or update this connector' + ) + ).toBeInTheDocument(); + expect(screen.getByTestId('legacy-connector-warning-callout')).toHaveClass( + 'euiCallOut euiCallOut--warning' + ); + }); + + test('it renders a danger flyout correctly', () => { + render(<DeprecatedCallout type="danger" />); + expect(screen.getByTestId('legacy-connector-warning-callout')).toHaveClass( + 'euiCallOut euiCallOut--danger' + ); + }); +}); diff --git a/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx b/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx new file mode 100644 index 0000000000000..937f8406e218a --- /dev/null +++ b/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { EuiCallOut, EuiCallOutProps } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +const LEGACY_CONNECTOR_WARNING_TITLE = i18n.translate( + 'xpack.cases.connectors.serviceNow.legacyConnectorWarningTitle', + { + defaultMessage: 'Deprecated connector type', + } +); + +const LEGACY_CONNECTOR_WARNING_DESC = i18n.translate( + 'xpack.cases.connectors.serviceNow.legacyConnectorWarningDesc', + { + defaultMessage: + 'This connector type is deprecated. Create a new connector or update this connector', + } +); + +interface Props { + type?: EuiCallOutProps['color']; +} + +const DeprecatedCalloutComponent: React.FC<Props> = ({ type = 'warning' }) => ( + <EuiCallOut + title={LEGACY_CONNECTOR_WARNING_TITLE} + color={type} + iconType="alert" + data-test-subj="legacy-connector-warning-callout" + > + {LEGACY_CONNECTOR_WARNING_DESC} + </EuiCallOut> +); + +export const DeprecatedCallout = React.memo(DeprecatedCalloutComponent); diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx index b14842bbf1bbf..008340b6b7e97 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { waitFor, act } from '@testing-library/react'; +import { waitFor, act, render, screen } from '@testing-library/react'; import { EuiSelect } from '@elastic/eui'; import { mount } from 'enzyme'; @@ -127,6 +127,17 @@ describe('ServiceNowITSM Fields', () => { ); }); + test('it shows the deprecated callout when the connector is legacy', async () => { + const legacyConnector = { ...connector, config: { isLegacy: true } }; + render(<Fields fields={fields} onChange={onChange} connector={legacyConnector} />); + expect(screen.getByTestId('legacy-connector-warning-callout')).toBeInTheDocument(); + }); + + test('it does not show the deprecated callout when the connector is not legacy', async () => { + render(<Fields fields={fields} onChange={onChange} connector={connector} />); + expect(screen.queryByTestId('legacy-connector-warning-callout')).not.toBeInTheDocument(); + }); + describe('onChange calls', () => { const wrapper = mount(<Fields fields={fields} onChange={onChange} connector={connector} />); diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.tsx index 53c0d32dea1a5..096e450c736c1 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.tsx @@ -16,6 +16,8 @@ import { ConnectorCard } from '../card'; import { useGetChoices } from './use_get_choices'; import { Fields, Choice } from './types'; import { choicesToEuiOptions } from './helpers'; +import { connectorValidator } from './validator'; +import { DeprecatedCallout } from '../deprecated_callout'; const useGetChoicesFields = ['urgency', 'severity', 'impact', 'category', 'subcategory']; const defaultFields: Fields = { @@ -39,6 +41,7 @@ const ServiceNowITSMFieldsComponent: React.FunctionComponent< } = fields ?? {}; const { http, notifications } = useKibana().services; const [choices, setChoices] = useState<Fields>(defaultFields); + const showConnectorWarning = useMemo(() => connectorValidator(connector) != null, [connector]); const categoryOptions = useMemo(() => choicesToEuiOptions(choices.category), [choices.category]); const urgencyOptions = useMemo(() => choicesToEuiOptions(choices.urgency), [choices.urgency]); @@ -149,90 +152,111 @@ const ServiceNowITSMFieldsComponent: React.FunctionComponent< } }, [category, impact, onChange, severity, subcategory, urgency]); - return isEdit ? ( - <div data-test-subj={'connector-fields-sn-itsm'}> - <EuiFormRow fullWidth label={i18n.URGENCY}> - <EuiSelect - fullWidth - data-test-subj="urgencySelect" - options={urgencyOptions} - value={urgency ?? undefined} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChangeCb('urgency', e.target.value)} - /> - </EuiFormRow> - <EuiSpacer size="m" /> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.SEVERITY}> - <EuiSelect - fullWidth - data-test-subj="severitySelect" - options={severityOptions} - value={severity ?? undefined} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChangeCb('severity', e.target.value)} + return ( + <> + {showConnectorWarning && ( + <EuiFlexGroup> + <EuiFlexItem> + <DeprecatedCallout type={isEdit ? 'danger' : 'warning'} /> + </EuiFlexItem> + </EuiFlexGroup> + )} + {isEdit ? ( + <div data-test-subj="connector-fields-sn-itsm"> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.URGENCY}> + <EuiSelect + fullWidth + data-test-subj="urgencySelect" + options={urgencyOptions} + value={urgency ?? undefined} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => onChangeCb('urgency', e.target.value)} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer size="m" /> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.SEVERITY}> + <EuiSelect + fullWidth + data-test-subj="severitySelect" + options={severityOptions} + value={severity ?? undefined} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => onChangeCb('severity', e.target.value)} + /> + </EuiFormRow> + </EuiFlexItem> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.IMPACT}> + <EuiSelect + fullWidth + data-test-subj="impactSelect" + options={impactOptions} + value={impact ?? undefined} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => onChangeCb('impact', e.target.value)} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.CATEGORY}> + <EuiSelect + fullWidth + data-test-subj="categorySelect" + options={categoryOptions} + value={category ?? undefined} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => + onChange({ ...fields, category: e.target.value, subcategory: null }) + } + /> + </EuiFormRow> + </EuiFlexItem> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.SUBCATEGORY}> + <EuiSelect + fullWidth + data-test-subj="subcategorySelect" + options={subcategoryOptions} + // Needs an empty string instead of undefined to select the blank option when changing categories + value={subcategory ?? ''} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => onChangeCb('subcategory', e.target.value)} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + </div> + ) : ( + <EuiFlexGroup> + <EuiFlexItem> + <ConnectorCard + connectorType={ConnectorTypes.serviceNowITSM} + title={connector.name} + listItems={listItems} + isLoading={false} /> - </EuiFormRow> - </EuiFlexItem> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.IMPACT}> - <EuiSelect - fullWidth - data-test-subj="impactSelect" - options={impactOptions} - value={impact ?? undefined} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChangeCb('impact', e.target.value)} - /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.CATEGORY}> - <EuiSelect - fullWidth - data-test-subj="categorySelect" - options={categoryOptions} - value={category ?? undefined} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChange({ ...fields, category: e.target.value, subcategory: null })} - /> - </EuiFormRow> - </EuiFlexItem> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.SUBCATEGORY}> - <EuiSelect - fullWidth - data-test-subj="subcategorySelect" - options={subcategoryOptions} - // Needs an empty string instead of undefined to select the blank option when changing categories - value={subcategory ?? ''} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChangeCb('subcategory', e.target.value)} - /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - </div> - ) : ( - <ConnectorCard - connectorType={ConnectorTypes.serviceNowITSM} - title={connector.name} - listItems={listItems} - isLoading={false} - /> + </EuiFlexItem> + </EuiFlexGroup> + )} + </> ); }; diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx index 7d42c90a436f7..aac78b8266fb5 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { waitFor, act } from '@testing-library/react'; +import { waitFor, act, render, screen } from '@testing-library/react'; import { EuiSelect } from '@elastic/eui'; import { useKibana } from '../../../common/lib/kibana'; @@ -68,16 +68,16 @@ describe('ServiceNowSIR Fields', () => { wrapper.update(); expect(wrapper.find('[data-test-subj="card-list-item"]').at(0).text()).toEqual( - 'Destination IP: Yes' + 'Destination IPs: Yes' ); expect(wrapper.find('[data-test-subj="card-list-item"]').at(1).text()).toEqual( - 'Source IP: Yes' + 'Source IPs: Yes' ); expect(wrapper.find('[data-test-subj="card-list-item"]').at(2).text()).toEqual( - 'Malware URL: Yes' + 'Malware URLs: Yes' ); expect(wrapper.find('[data-test-subj="card-list-item"]').at(3).text()).toEqual( - 'Malware Hash: Yes' + 'Malware Hashes: Yes' ); expect(wrapper.find('[data-test-subj="card-list-item"]').at(4).text()).toEqual( 'Priority: 1 - Critical' @@ -161,6 +161,17 @@ describe('ServiceNowSIR Fields', () => { ]); }); + test('it shows the deprecated callout when the connector is legacy', async () => { + const legacyConnector = { ...connector, config: { isLegacy: true } }; + render(<Fields fields={fields} onChange={onChange} connector={legacyConnector} />); + expect(screen.getByTestId('legacy-connector-warning-callout')).toBeInTheDocument(); + }); + + test('it does not show the deprecated callout when the connector is not legacy', async () => { + render(<Fields fields={fields} onChange={onChange} connector={connector} />); + expect(screen.queryByTestId('legacy-connector-warning-callout')).not.toBeInTheDocument(); + }); + describe('onChange calls', () => { const wrapper = mount(<Fields fields={fields} onChange={onChange} connector={connector} />); diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.tsx index 1f9a7cf7acd64..a7b8aa7b27df5 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.tsx @@ -17,6 +17,8 @@ import { Choice, Fields } from './types'; import { choicesToEuiOptions } from './helpers'; import * as i18n from './translations'; +import { connectorValidator } from './validator'; +import { DeprecatedCallout } from '../deprecated_callout'; const useGetChoicesFields = ['category', 'subcategory', 'priority']; const defaultFields: Fields = { @@ -40,8 +42,8 @@ const ServiceNowSIRFieldsComponent: React.FunctionComponent< } = fields ?? {}; const { http, notifications } = useKibana().services; - const [choices, setChoices] = useState<Fields>(defaultFields); + const showConnectorWarning = useMemo(() => connectorValidator(connector) != null, [connector]); const onChangeCb = useCallback( ( @@ -166,115 +168,132 @@ const ServiceNowSIRFieldsComponent: React.FunctionComponent< } }, [category, destIp, malwareHash, malwareUrl, onChange, priority, sourceIp, subcategory]); - return isEdit ? ( - <div data-test-subj={'connector-fields-sn-sir'}> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.ALERT_FIELDS_LABEL}> - <> - <EuiFlexGroup> - <EuiFlexItem> - <EuiCheckbox - id="destIpCheckbox" - data-test-subj="destIpCheckbox" - label={i18n.DEST_IP} - checked={destIp ?? false} - compressed - onChange={(e) => onChangeCb('destIp', e.target.checked)} - /> - </EuiFlexItem> - <EuiFlexItem> - <EuiCheckbox - id="sourceIpCheckbox" - data-test-subj="sourceIpCheckbox" - label={i18n.SOURCE_IP} - checked={sourceIp ?? false} - compressed - onChange={(e) => onChangeCb('sourceIp', e.target.checked)} - /> - </EuiFlexItem> - </EuiFlexGroup> - <EuiFlexGroup> - <EuiFlexItem> - <EuiCheckbox - id="malwareUrlCheckbox" - data-test-subj="malwareUrlCheckbox" - label={i18n.MALWARE_URL} - checked={malwareUrl ?? false} - compressed - onChange={(e) => onChangeCb('malwareUrl', e.target.checked)} - /> - </EuiFlexItem> - <EuiFlexItem> - <EuiCheckbox - id="malwareHashCheckbox" - data-test-subj="malwareHashCheckbox" - label={i18n.MALWARE_HASH} - checked={malwareHash ?? false} - compressed - onChange={(e) => onChangeCb('malwareHash', e.target.checked)} - /> - </EuiFlexItem> - </EuiFlexGroup> - </> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.PRIORITY}> - <EuiSelect - fullWidth - data-test-subj="prioritySelect" - hasNoInitialSelection - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - options={priorityOptions} - value={priority ?? undefined} - onChange={(e) => onChangeCb('priority', e.target.value)} - /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.CATEGORY}> - <EuiSelect - fullWidth - data-test-subj="categorySelect" - options={categoryOptions} - value={category ?? undefined} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChange({ ...fields, category: e.target.value, subcategory: null })} - /> - </EuiFormRow> - </EuiFlexItem> - <EuiFlexItem> - <EuiFormRow fullWidth label={i18n.SUBCATEGORY}> - <EuiSelect - fullWidth - data-test-subj="subcategorySelect" - options={subcategoryOptions} - // Needs an empty string instead of undefined to select the blank option when changing categories - value={subcategory ?? ''} - isLoading={isLoadingChoices} - disabled={isLoadingChoices} - hasNoInitialSelection - onChange={(e) => onChangeCb('subcategory', e.target.value)} + return ( + <> + {showConnectorWarning && ( + <EuiFlexGroup> + <EuiFlexItem> + <DeprecatedCallout type={isEdit ? 'danger' : 'warning'} /> + </EuiFlexItem> + </EuiFlexGroup> + )} + {isEdit ? ( + <div data-test-subj="connector-fields-sn-sir"> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.ALERT_FIELDS_LABEL}> + <> + <EuiFlexGroup> + <EuiFlexItem> + <EuiCheckbox + id="destIpCheckbox" + data-test-subj="destIpCheckbox" + label={i18n.DEST_IP} + checked={destIp ?? false} + compressed + onChange={(e) => onChangeCb('destIp', e.target.checked)} + /> + </EuiFlexItem> + <EuiFlexItem> + <EuiCheckbox + id="sourceIpCheckbox" + data-test-subj="sourceIpCheckbox" + label={i18n.SOURCE_IP} + checked={sourceIp ?? false} + compressed + onChange={(e) => onChangeCb('sourceIp', e.target.checked)} + /> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup> + <EuiFlexItem> + <EuiCheckbox + id="malwareUrlCheckbox" + data-test-subj="malwareUrlCheckbox" + label={i18n.MALWARE_URL} + checked={malwareUrl ?? false} + compressed + onChange={(e) => onChangeCb('malwareUrl', e.target.checked)} + /> + </EuiFlexItem> + <EuiFlexItem> + <EuiCheckbox + id="malwareHashCheckbox" + data-test-subj="malwareHashCheckbox" + label={i18n.MALWARE_HASH} + checked={malwareHash ?? false} + compressed + onChange={(e) => onChangeCb('malwareHash', e.target.checked)} + /> + </EuiFlexItem> + </EuiFlexGroup> + </> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.PRIORITY}> + <EuiSelect + fullWidth + data-test-subj="prioritySelect" + hasNoInitialSelection + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + options={priorityOptions} + value={priority ?? undefined} + onChange={(e) => onChangeCb('priority', e.target.value)} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.CATEGORY}> + <EuiSelect + fullWidth + data-test-subj="categorySelect" + options={categoryOptions} + value={category ?? undefined} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => + onChange({ ...fields, category: e.target.value, subcategory: null }) + } + /> + </EuiFormRow> + </EuiFlexItem> + <EuiFlexItem> + <EuiFormRow fullWidth label={i18n.SUBCATEGORY}> + <EuiSelect + fullWidth + data-test-subj="subcategorySelect" + options={subcategoryOptions} + // Needs an empty string instead of undefined to select the blank option when changing categories + value={subcategory ?? ''} + isLoading={isLoadingChoices} + disabled={isLoadingChoices} + hasNoInitialSelection + onChange={(e) => onChangeCb('subcategory', e.target.value)} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + </div> + ) : ( + <EuiFlexGroup> + <EuiFlexItem> + <ConnectorCard + connectorType={ConnectorTypes.serviceNowSIR} + title={connector.name} + listItems={listItems} + isLoading={false} /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - </div> - ) : ( - <ConnectorCard - connectorType={ConnectorTypes.serviceNowITSM} - title={connector.name} - listItems={listItems} - isLoading={false} - /> + </EuiFlexItem> + </EuiFlexGroup> + )} + </> ); }; diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/translations.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/translations.ts index fc48ecf17f2c6..d9ed86b594ecc 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/translations.ts +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/translations.ts @@ -30,11 +30,11 @@ export const CHOICES_API_ERROR = i18n.translate( ); export const MALWARE_URL = i18n.translate('xpack.cases.connectors.serviceNow.malwareURLTitle', { - defaultMessage: 'Malware URL', + defaultMessage: 'Malware URLs', }); export const MALWARE_HASH = i18n.translate('xpack.cases.connectors.serviceNow.malwareHashTitle', { - defaultMessage: 'Malware Hash', + defaultMessage: 'Malware Hashes', }); export const CATEGORY = i18n.translate('xpack.cases.connectors.serviceNow.categoryTitle', { @@ -46,11 +46,11 @@ export const SUBCATEGORY = i18n.translate('xpack.cases.connectors.serviceNow.sub }); export const SOURCE_IP = i18n.translate('xpack.cases.connectors.serviceNow.sourceIPTitle', { - defaultMessage: 'Source IP', + defaultMessage: 'Source IPs', }); export const DEST_IP = i18n.translate('xpack.cases.connectors.serviceNow.destinationIPTitle', { - defaultMessage: 'Destination IP', + defaultMessage: 'Destination IPs', }); export const PRIORITY = i18n.translate( diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts new file mode 100644 index 0000000000000..c098d803276bc --- /dev/null +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.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 { connector } from '../mock'; +import { connectorValidator } from './validator'; + +describe('ServiceNow validator', () => { + describe('connectorValidator', () => { + test('it returns an error message if the connector is legacy', () => { + const invalidConnector = { + ...connector, + config: { + ...connector.config, + isLegacy: true, + }, + }; + + expect(connectorValidator(invalidConnector)).toEqual({ message: 'Deprecated connector' }); + }); + + test('it does not returns an error message if the connector is not legacy', () => { + const invalidConnector = { + ...connector, + config: { + ...connector.config, + isLegacy: false, + }, + }; + + expect(connectorValidator(invalidConnector)).toBeFalsy(); + }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts new file mode 100644 index 0000000000000..3f67f25549343 --- /dev/null +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.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 { ValidationConfig } from '../../../common/shared_imports'; +import { CaseActionConnector } from '../../types'; + +/** + * The user can not use a legacy connector + */ + +export const connectorValidator = ( + connector: CaseActionConnector +): ReturnType<ValidationConfig['validator']> => { + const { + config: { isLegacy }, + } = connector; + if (isLegacy) { + return { + message: 'Deprecated connector', + }; + } +}; diff --git a/x-pack/plugins/cases/public/components/create/connector.test.tsx b/x-pack/plugins/cases/public/components/create/connector.test.tsx index a2ffd42f2660b..ea7435c2cba45 100644 --- a/x-pack/plugins/cases/public/components/create/connector.test.tsx +++ b/x-pack/plugins/cases/public/components/create/connector.test.tsx @@ -22,8 +22,8 @@ import { TestProviders } from '../../common/mock'; import { useCaseConfigure } from '../../containers/configure/use_configure'; import { useCaseConfigureResponse } from '../configure_cases/__mock__'; import { triggersActionsUiMock } from '../../../../triggers_actions_ui/public/mocks'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; import { useKibana } from '../../common/lib/kibana'; +import { registerConnectorsToMockActionRegistry } from '../../common/mock/register_connectors'; const mockTriggersActionsUiService = triggersActionsUiMock.createStart(); @@ -86,14 +86,10 @@ describe('Connector', () => { return <Form form={form}>{children}</Form>; }; - const { createMockActionTypeModel } = actionTypeRegistryMock; + const actionTypeRegistry = useKibanaMock().services.triggersActionsUi.actionTypeRegistry; beforeAll(() => { - connectorsMock.forEach((connector) => - useKibanaMock().services.triggersActionsUi.actionTypeRegistry.register( - createMockActionTypeModel({ id: connector.actionTypeId, iconClass: 'logoSecurity' }) - ) - ); + registerConnectorsToMockActionRegistry(actionTypeRegistry, connectorsMock); }); beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/types.ts b/x-pack/plugins/cases/public/components/types.ts index 014afc371e761..07ab5814b082b 100644 --- a/x-pack/plugins/cases/public/components/types.ts +++ b/x-pack/plugins/cases/public/components/types.ts @@ -5,6 +5,4 @@ * 2.0. */ -import { ActionConnector } from '../../common'; - -export type CaseActionConnector = ActionConnector; +export { CaseActionConnector } from '../../common'; diff --git a/x-pack/plugins/cases/public/components/utils.ts b/x-pack/plugins/cases/public/components/utils.ts index 5f7480cb84f7c..ac5f4dbdd298e 100644 --- a/x-pack/plugins/cases/public/components/utils.ts +++ b/x-pack/plugins/cases/public/components/utils.ts @@ -10,7 +10,13 @@ import { ConnectorTypes } from '../../common'; import { FieldConfig, ValidationConfig } from '../common/shared_imports'; import { StartPlugins } from '../types'; import { connectorValidator as swimlaneConnectorValidator } from './connectors/swimlane/validator'; +import { connectorValidator as servicenowConnectorValidator } from './connectors/servicenow/validator'; import { CaseActionConnector } from './types'; +import { + ENABLE_NEW_SN_ITSM_CONNECTOR, + ENABLE_NEW_SN_SIR_CONNECTOR, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../actions/server/constants/connectors'; export const getConnectorById = ( id: string, @@ -22,6 +28,8 @@ const validators: Record< (connector: CaseActionConnector) => ReturnType<ValidationConfig['validator']> > = { [ConnectorTypes.swimlane]: swimlaneConnectorValidator, + [ConnectorTypes.serviceNowITSM]: servicenowConnectorValidator, + [ConnectorTypes.serviceNowSIR]: servicenowConnectorValidator, }; export const getConnectorsFormValidators = ({ @@ -68,3 +76,20 @@ export const getConnectorIcon = ( return emptyResponse; }; + +// TODO: Remove when the applications are certified +export const isLegacyConnector = (connector?: CaseActionConnector) => { + if (connector == null) { + return true; + } + + if (!ENABLE_NEW_SN_ITSM_CONNECTOR && connector.actionTypeId === '.servicenow') { + return true; + } + + if (!ENABLE_NEW_SN_SIR_CONNECTOR && connector.actionTypeId === '.servicenow-sir') { + return true; + } + + return connector.config.isLegacy; +}; diff --git a/x-pack/plugins/cases/public/containers/configure/mock.ts b/x-pack/plugins/cases/public/containers/configure/mock.ts index 833c2cfb3aa7c..d1ae7f310a719 100644 --- a/x-pack/plugins/cases/public/containers/configure/mock.ts +++ b/x-pack/plugins/cases/public/containers/configure/mock.ts @@ -71,6 +71,16 @@ export const connectorsMock: ActionConnector[] = [ }, isPreconfigured: false, }, + { + id: 'servicenow-legacy', + actionTypeId: '.servicenow', + name: 'My Connector', + config: { + apiUrl: 'https://instance1.service-now.com', + isLegacy: true, + }, + isPreconfigured: false, + }, ]; export const actionTypesMock: ActionTypeConnector[] = [ diff --git a/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.test.ts b/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.test.ts index 2cc1816e7fa67..ac9dc8839bfb8 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.test.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.test.ts @@ -10,6 +10,7 @@ import { format } from './itsm_format'; describe('ITSM formatter', () => { const theCase = { + id: 'case-id', connector: { fields: { severity: '2', urgency: '2', impact: '2', category: 'software', subcategory: 'os' }, }, @@ -17,7 +18,11 @@ describe('ITSM formatter', () => { it('it formats correctly', async () => { const res = await format(theCase, []); - expect(res).toEqual(theCase.connector.fields); + expect(res).toEqual({ + ...theCase.connector.fields, + correlation_display: 'Elastic Case', + correlation_id: 'case-id', + }); }); it('it formats correctly when fields do not exist ', async () => { @@ -29,6 +34,8 @@ describe('ITSM formatter', () => { impact: null, category: null, subcategory: null, + correlation_display: 'Elastic Case', + correlation_id: null, }); }); }); diff --git a/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.ts b/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.ts index bc9d50026d1f8..1859ea1246f21 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/itsm_format.ts @@ -16,5 +16,13 @@ export const format: ServiceNowITSMFormat = (theCase, alerts) => { category = null, subcategory = null, } = (theCase.connector.fields as ConnectorServiceNowITSMTypeFields['fields']) ?? {}; - return { severity, urgency, impact, category, subcategory }; + return { + severity, + urgency, + impact, + category, + subcategory, + correlation_id: theCase.id ?? null, + correlation_display: 'Elastic Case', + }; }; diff --git a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts index fa103d4c1142d..b09272d0a5505 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts @@ -10,6 +10,7 @@ import { format } from './sir_format'; describe('ITSM formatter', () => { const theCase = { + id: 'case-id', connector: { fields: { destIp: true, @@ -26,13 +27,15 @@ describe('ITSM formatter', () => { it('it formats correctly without alerts', async () => { const res = await format(theCase, []); expect(res).toEqual({ - dest_ip: null, - source_ip: null, + dest_ip: [], + source_ip: [], category: 'Denial of Service', subcategory: 'Inbound DDos', - malware_hash: null, - malware_url: null, + malware_hash: [], + malware_url: [], priority: '2 - High', + correlation_display: 'Elastic Case', + correlation_id: 'case-id', }); }); @@ -40,13 +43,15 @@ describe('ITSM formatter', () => { const invalidFields = { connector: { fields: null } } as CaseResponse; const res = await format(invalidFields, []); expect(res).toEqual({ - dest_ip: null, - source_ip: null, + dest_ip: [], + source_ip: [], category: null, subcategory: null, - malware_hash: null, - malware_url: null, + malware_hash: [], + malware_url: [], priority: null, + correlation_display: 'Elastic Case', + correlation_id: null, }); }); @@ -75,14 +80,18 @@ describe('ITSM formatter', () => { ]; const res = await format(theCase, alerts); expect(res).toEqual({ - dest_ip: '192.168.1.1,192.168.1.4', - source_ip: '192.168.1.2,192.168.1.3', + dest_ip: ['192.168.1.1', '192.168.1.4'], + source_ip: ['192.168.1.2', '192.168.1.3'], category: 'Denial of Service', subcategory: 'Inbound DDos', - malware_hash: - '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08,60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752', - malware_url: 'https://attack.com,https://attack.com/api', + malware_hash: [ + '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752', + ], + malware_url: ['https://attack.com', 'https://attack.com/api'], priority: '2 - High', + correlation_display: 'Elastic Case', + correlation_id: 'case-id', }); }); @@ -111,13 +120,15 @@ describe('ITSM formatter', () => { ]; const res = await format(theCase, alerts); expect(res).toEqual({ - dest_ip: '192.168.1.1', - source_ip: '192.168.1.2,192.168.1.3', + dest_ip: ['192.168.1.1'], + source_ip: ['192.168.1.2', '192.168.1.3'], category: 'Denial of Service', subcategory: 'Inbound DDos', - malware_hash: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', - malware_url: 'https://attack.com,https://attack.com/api', + malware_hash: ['9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'], + malware_url: ['https://attack.com', 'https://attack.com/api'], priority: '2 - High', + correlation_display: 'Elastic Case', + correlation_id: 'case-id', }); }); @@ -152,13 +163,15 @@ describe('ITSM formatter', () => { const res = await format(newCase, alerts); expect(res).toEqual({ - dest_ip: null, - source_ip: '192.168.1.2,192.168.1.3', + dest_ip: [], + source_ip: ['192.168.1.2', '192.168.1.3'], category: 'Denial of Service', subcategory: 'Inbound DDos', - malware_hash: null, - malware_url: 'https://attack.com,https://attack.com/api', + malware_hash: [], + malware_url: ['https://attack.com', 'https://attack.com/api'], priority: '2 - High', + correlation_display: 'Elastic Case', + correlation_id: 'case-id', }); }); }); diff --git a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts index b48a1b7f734c8..9108408c4d089 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts @@ -32,11 +32,11 @@ export const format: ServiceNowSIRFormat = (theCase, alerts) => { malware_url: new Set(), }; - let sirFields: Record<SirFieldKey, string | null> = { - dest_ip: null, - source_ip: null, - malware_hash: null, - malware_url: null, + let sirFields: Record<SirFieldKey, string[]> = { + dest_ip: [], + source_ip: [], + malware_hash: [], + malware_url: [], }; const fieldsToAdd = (Object.keys(alertFieldMapping) as SirFieldKey[]).filter( @@ -44,18 +44,17 @@ export const format: ServiceNowSIRFormat = (theCase, alerts) => { ); if (fieldsToAdd.length > 0) { - sirFields = alerts.reduce<Record<SirFieldKey, string | null>>((acc, alert) => { + sirFields = alerts.reduce<Record<SirFieldKey, string[]>>((acc, alert) => { fieldsToAdd.forEach((alertField) => { const field = get(alertFieldMapping[alertField].alertPath, alert); if (field && !manageDuplicate[alertFieldMapping[alertField].sirFieldKey].has(field)) { manageDuplicate[alertFieldMapping[alertField].sirFieldKey].add(field); acc = { ...acc, - [alertFieldMapping[alertField].sirFieldKey]: `${ - acc[alertFieldMapping[alertField].sirFieldKey] != null - ? `${acc[alertFieldMapping[alertField].sirFieldKey]},${field}` - : field - }`, + [alertFieldMapping[alertField].sirFieldKey]: [ + ...acc[alertFieldMapping[alertField].sirFieldKey], + field, + ], }; } }); @@ -68,5 +67,7 @@ export const format: ServiceNowSIRFormat = (theCase, alerts) => { category, subcategory, priority, + correlation_id: theCase.id ?? null, + correlation_display: 'Elastic Case', }; }; diff --git a/x-pack/plugins/cases/server/connectors/servicenow/types.ts b/x-pack/plugins/cases/server/connectors/servicenow/types.ts index 2caebc3dab316..b0e71cbe5e743 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/types.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/types.ts @@ -8,13 +8,18 @@ import { ServiceNowITSMFieldsType } from '../../../common'; import { ICasesConnector } from '../types'; -export interface ServiceNowSIRFieldsType { - dest_ip: string | null; - source_ip: string | null; +interface CorrelationValues { + correlation_id: string | null; + correlation_display: string | null; +} + +export interface ServiceNowSIRFieldsType extends CorrelationValues { + dest_ip: string[] | null; + source_ip: string[] | null; category: string | null; subcategory: string | null; - malware_hash: string | null; - malware_url: string | null; + malware_hash: string[] | null; + malware_url: string[] | null; priority: string | null; } @@ -26,7 +31,9 @@ export type AlertFieldMappingAndValues = Record< // ServiceNow ITSM export type ServiceNowITSMCasesConnector = ICasesConnector<ServiceNowITSMFieldsType>; -export type ServiceNowITSMFormat = ICasesConnector<ServiceNowITSMFieldsType>['format']; +export type ServiceNowITSMFormat = ICasesConnector< + ServiceNowITSMFieldsType & CorrelationValues +>['format']; export type ServiceNowITSMGetMapping = ICasesConnector<ServiceNowITSMFieldsType>['getMapping']; // ServiceNow SIR diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx index d8d5d9d10b3b7..df7ea80779acf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx @@ -9,7 +9,16 @@ import React from 'react'; import { useActions } from 'kea'; -import { EuiCode, EuiFieldText, EuiLink, EuiSelect, EuiText } from '@elastic/eui'; +import { + EuiCode, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiLink, + EuiSelect, + EuiText, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -27,6 +36,7 @@ import { getReadableCrawlerPolicy, getReadableCrawlerRule, } from '../types'; +import { getCrawlRulePathPatternTooltip } from '../utils'; interface CrawlRulesTableProps { description?: React.ReactNode; @@ -130,13 +140,24 @@ export const CrawlRulesTable: React.FC<CrawlRulesTableProps> = ({ }, { editingRender: (crawlRule, onChange, { isInvalid, isLoading }) => ( - <EuiFieldText - fullWidth - value={(crawlRule as CrawlRule).pattern} - onChange={(e) => onChange(e.target.value)} - disabled={isLoading} - isInvalid={isInvalid} - /> + <EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}> + <EuiFlexItem> + <EuiFieldText + fullWidth + value={(crawlRule as CrawlRule).pattern} + onChange={(e) => onChange(e.target.value)} + disabled={isLoading} + isInvalid={isInvalid} + /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiIconTip + content={getCrawlRulePathPatternTooltip(crawlRule as CrawlRule)} + type="iInCircle" + position="top" + /> + </EuiFlexItem> + </EuiFlexGroup> ), render: (crawlRule) => <EuiCode>{(crawlRule as CrawlRule).pattern}</EuiCode>, name: i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts index fc810ba8fd7cb..0fc608ac6f5e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts @@ -26,6 +26,7 @@ import { crawlRequestServerToClient, getDeleteDomainConfirmationMessage, getDeleteDomainSuccessMessage, + getCrawlRulePathPatternTooltip, } from './utils'; const DEFAULT_CRAWL_RULE: CrawlRule = { @@ -292,3 +293,28 @@ describe('getDeleteDomainSuccessMessage', () => { expect(getDeleteDomainSuccessMessage('https://elastic.co/')).toContain('https://elastic.co'); }); }); + +describe('getCrawlRulePathPatternTooltip', () => { + it('includes regular expression', () => { + const crawlRule: CrawlRule = { + id: '-', + policy: CrawlerPolicies.allow, + rule: CrawlerRules.regex, + pattern: '.*', + }; + + expect(getCrawlRulePathPatternTooltip(crawlRule)).toContain('regular expression'); + }); + + it('includes meta', () => { + const crawlRule: CrawlRule = { + id: '-', + policy: CrawlerPolicies.allow, + rule: CrawlerRules.beginsWith, + pattern: '/elastic', + }; + + expect(getCrawlRulePathPatternTooltip(crawlRule)).not.toContain('regular expression'); + expect(getCrawlRulePathPatternTooltip(crawlRule)).toContain('meta'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts index 9c94040355d47..817f10b70dca5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts @@ -16,6 +16,8 @@ import { CrawlerDomainValidationStep, CrawlRequestFromServer, CrawlRequest, + CrawlRule, + CrawlerRules, CrawlEventFromServer, CrawlEvent, } from './types'; @@ -159,3 +161,23 @@ export const getDeleteDomainSuccessMessage = (domainUrl: string) => { } ); }; + +export const getCrawlRulePathPatternTooltip = (crawlRule: CrawlRule) => { + if (crawlRule.rule === CrawlerRules.regex) { + return i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.crawlRulesTable.regexPathPatternTooltip', + { + defaultMessage: + 'The path pattern is a regular expression compatible with the Ruby language regular expression engine.', + } + ); + } + + return i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.crawlRulesTable.pathPatternTooltip', + { + defaultMessage: + 'The path pattern is a literal string except for the asterisk (*) character, which is a meta character that will match anything.', + } + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.ts index e623379e58d3f..04d04b297050a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_logic.ts @@ -23,7 +23,7 @@ import { EngineLogic, generateEnginePath } from '../engine'; import { DELETE_CONFIRMATION_MESSAGE, DELETE_SUCCESS_MESSAGE } from './constants'; import { Curation, CurationsAPIResponse } from './types'; -type CurationsPageTabs = 'overview' | 'settings'; +type CurationsPageTabs = 'overview' | 'settings' | 'history'; interface CurationsValues { dataLoading: boolean; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx index 7e357cae4343c..f7e9f5437fc3f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx @@ -19,6 +19,7 @@ import { EuiTab } from '@elastic/eui'; import { getPageHeaderTabs, getPageTitle } from '../../../../test_helpers'; import { Curations } from './curations'; +import { CurationsHistory } from './curations_history/curations_history'; import { CurationsOverview } from './curations_overview'; import { CurationsSettings } from './curations_settings'; @@ -70,7 +71,10 @@ describe('Curations', () => { expect(actions.onSelectPageTab).toHaveBeenNthCalledWith(1, 'overview'); tabs.at(1).simulate('click'); - expect(actions.onSelectPageTab).toHaveBeenNthCalledWith(2, 'settings'); + expect(actions.onSelectPageTab).toHaveBeenNthCalledWith(2, 'history'); + + tabs.at(2).simulate('click'); + expect(actions.onSelectPageTab).toHaveBeenNthCalledWith(3, 'settings'); }); it('renders an overview view', () => { @@ -83,12 +87,22 @@ describe('Curations', () => { expect(wrapper.find(CurationsOverview)).toHaveLength(1); }); + it('renders a history view', () => { + setMockValues({ ...values, selectedPageTab: 'history' }); + const wrapper = shallow(<Curations />); + const tabs = getPageHeaderTabs(wrapper).find(EuiTab); + + expect(tabs.at(1).prop('isSelected')).toEqual(true); + + expect(wrapper.find(CurationsHistory)).toHaveLength(1); + }); + it('renders a settings view', () => { setMockValues({ ...values, selectedPageTab: 'settings' }); const wrapper = shallow(<Curations />); const tabs = getPageHeaderTabs(wrapper).find(EuiTab); - expect(tabs.at(1).prop('isSelected')).toEqual(true); + expect(tabs.at(2).prop('isSelected')).toEqual(true); expect(wrapper.find(CurationsSettings)).toHaveLength(1); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx index 9584b21424fe3..c55fde7626488 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx @@ -21,6 +21,7 @@ import { CURATIONS_OVERVIEW_TITLE, CREATE_NEW_CURATION_TITLE } from '../constant import { CurationsLogic } from '../curations_logic'; import { getCurationsBreadcrumbs } from '../utils'; +import { CurationsHistory } from './curations_history/curations_history'; import { CurationsOverview } from './curations_overview'; import { CurationsSettings } from './curations_settings'; @@ -39,6 +40,16 @@ export const Curations: React.FC = () => { isSelected: selectedPageTab === 'overview', onClick: () => onSelectPageTab('overview'), }, + { + label: i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.historyPageTabLabel', + { + defaultMessage: 'History', + } + ), + isSelected: selectedPageTab === 'history', + onClick: () => onSelectPageTab('history'), + }, { label: i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.curations.settingsPageTabLabel', @@ -74,6 +85,7 @@ export const Curations: React.FC = () => { isLoading={dataLoading && !curations.length} > {selectedPageTab === 'overview' && <CurationsOverview />} + {selectedPageTab === 'history' && <CurationsHistory />} {selectedPageTab === 'settings' && <CurationsSettings />} </AppSearchPageTemplate> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/curation_changes_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/curation_changes_panel.test.tsx new file mode 100644 index 0000000000000..7fc06beaa86a9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/curation_changes_panel.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { DataPanel } from '../../../../data_panel'; + +import { CurationChangesPanel } from './curation_changes_panel'; + +describe('CurationChangesPanel', () => { + it('renders', () => { + const wrapper = shallow(<CurationChangesPanel />); + + expect(wrapper.is(DataPanel)).toBe(true); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/curation_changes_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/curation_changes_panel.tsx new file mode 100644 index 0000000000000..0aaf20485966e --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/curation_changes_panel.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { DataPanel } from '../../../../data_panel'; + +export const CurationChangesPanel: React.FC = () => { + return ( + <DataPanel + title={<h2>Automated curation changes</h2>} + subtitle={<span>A detailed log of recent changes to your automated curations</span>} + iconType="visTable" + hasBorder + > + Embedded logs view goes here... + </DataPanel> + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_suggestions_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_suggestions_panel.test.tsx new file mode 100644 index 0000000000000..b09981748f19c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_suggestions_panel.test.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 from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiBasicTable } from '@elastic/eui'; + +import { DataPanel } from '../../../../data_panel'; + +import { IgnoredSuggestionsPanel } from './ignored_suggestions_panel'; + +describe('IgnoredSuggestionsPanel', () => { + it('renders', () => { + const wrapper = shallow(<IgnoredSuggestionsPanel />); + + expect(wrapper.is(DataPanel)).toBe(true); + expect(wrapper.find(EuiBasicTable)).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_suggestions_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_suggestions_panel.tsx new file mode 100644 index 0000000000000..f2fdfd55a7e5a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_suggestions_panel.tsx @@ -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 React from 'react'; + +import { CustomItemAction, EuiBasicTable, EuiBasicTableColumn, EuiLink } from '@elastic/eui'; + +import { DataPanel } from '../../../../data_panel'; +import { CurationSuggestion } from '../../../types'; + +export const IgnoredSuggestionsPanel: React.FC = () => { + const ignoredSuggestions: CurationSuggestion[] = []; + + const allowSuggestion = (query: string) => alert(query); + + const actions: Array<CustomItemAction<CurationSuggestion>> = [ + { + render: (item: CurationSuggestion) => { + return ( + <EuiLink onClick={() => allowSuggestion(item.query)} color="primary"> + Allow + </EuiLink> + ); + }, + }, + ]; + + const columns: Array<EuiBasicTableColumn<CurationSuggestion>> = [ + { + field: 'query', + name: 'Query', + sortable: true, + }, + { + actions, + }, + ]; + + return ( + <DataPanel + title={<h2>Ignored queries</h2>} + subtitle={<span>You won’t be notified about suggestions for these queries</span>} + iconType="eyeClosed" + hasBorder + > + <EuiBasicTable items={ignoredSuggestions} itemId="query" columns={columns} /> + </DataPanel> + ); +}; diff --git a/x-pack/test/functional/apps/reporting/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/index.ts similarity index 53% rename from x-pack/test/functional/apps/reporting/index.ts rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/index.ts index 286693f01ac52..2e16d9bde8550 100644 --- a/x-pack/test/functional/apps/reporting/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/index.ts @@ -5,10 +5,6 @@ * 2.0. */ -import { FtrProviderContext } from '../../ftr_provider_context'; - -export default function ({ loadTestFile }: FtrProviderContext) { - describe('Reporting', function () { - loadTestFile(require.resolve('./reporting')); - }); -} +export { CurationChangesPanel } from './curation_changes_panel'; +export { IgnoredSuggestionsPanel } from './ignored_suggestions_panel'; +export { RejectedCurationsPanel } from './rejected_curations_panel'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/rejected_curations_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/rejected_curations_panel.test.tsx new file mode 100644 index 0000000000000..a40eb8895ad69 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/rejected_curations_panel.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { DataPanel } from '../../../../data_panel'; + +import { RejectedCurationsPanel } from './rejected_curations_panel'; + +describe('RejectedCurationsPanel', () => { + it('renders', () => { + const wrapper = shallow(<RejectedCurationsPanel />); + + expect(wrapper.is(DataPanel)).toBe(true); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/rejected_curations_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/rejected_curations_panel.tsx new file mode 100644 index 0000000000000..51719b4eebbd7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/rejected_curations_panel.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { DataPanel } from '../../../../data_panel'; + +export const RejectedCurationsPanel: React.FC = () => { + return ( + <DataPanel + title={<h2>Rececntly rejected sugggestions</h2>} + subtitle={<span>Recent suggestions that are still valid can be re-enabled from here</span>} + iconType="crossInACircleFilled" + hasBorder + > + Embedded logs view goes here... + </DataPanel> + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/curations_history.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/curations_history.test.tsx new file mode 100644 index 0000000000000..1ebd4da694d54 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/curations_history.test.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { + CurationChangesPanel, + IgnoredSuggestionsPanel, + RejectedCurationsPanel, +} from './components'; +import { CurationsHistory } from './curations_history'; + +describe('CurationsHistory', () => { + it('renders', () => { + const wrapper = shallow(<CurationsHistory />); + + expect(wrapper.find(CurationChangesPanel)).toHaveLength(1); + expect(wrapper.find(RejectedCurationsPanel)).toHaveLength(1); + expect(wrapper.find(IgnoredSuggestionsPanel)).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/curations_history.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/curations_history.tsx new file mode 100644 index 0000000000000..6db62820b1cdb --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/curations_history.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; + +import { + CurationChangesPanel, + IgnoredSuggestionsPanel, + RejectedCurationsPanel, +} from './components'; + +export const CurationsHistory: React.FC = () => { + return ( + <EuiFlexGroup> + <EuiFlexItem grow={2}> + <EuiFlexGroup direction="column"> + <EuiFlexItem> + <CurationChangesPanel /> + </EuiFlexItem> + <EuiFlexItem> + <RejectedCurationsPanel /> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFlexItem> + <EuiFlexItem grow={1}> + <IgnoredSuggestionsPanel /> + </EuiFlexItem> + </EuiFlexGroup> + ); +}; diff --git a/x-pack/test/api_integration/apis/xpack_legacy/settings/index.js b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/index.ts similarity index 65% rename from x-pack/test/api_integration/apis/xpack_legacy/settings/index.js rename to x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/index.ts index 3d8ce8d33b3d4..bddc156f7920e 100644 --- a/x-pack/test/api_integration/apis/xpack_legacy/settings/index.js +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/index.ts @@ -5,8 +5,4 @@ * 2.0. */ -export default function ({ loadTestFile }) { - describe('Settings', () => { - loadTestFile(require.resolve('./settings')); - }); -} +export { CurationsHistory } from './curations_history'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/constants/actions.ts b/x-pack/plugins/enterprise_search/public/applications/shared/constants/actions.ts index cb05311e11998..d43217fba1443 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/constants/actions.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/constants/actions.ts @@ -35,6 +35,11 @@ export const CANCEL_BUTTON_LABEL = i18n.translate( { defaultMessage: 'Cancel' } ); +export const START_BUTTON_LABEL = i18n.translate( + 'xpack.enterpriseSearch.actions.startButtonLabel', + { defaultMessage: 'Start' } +); + export const CONTINUE_BUTTON_LABEL = i18n.translate( 'xpack.enterpriseSearch.actions.continueButtonLabel', { defaultMessage: 'Continue' } diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts index fab241163f470..48cbf4ba00d87 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts @@ -54,6 +54,7 @@ const defaultIndexing = { incremental: 'PT2H', delete: 'PT10M', permissions: 'PT3H', + blockedWindows: [], estimates: { full: { nextStart: '2021-09-30T15:37:38+00:00', diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_sidebar/private_sources_sidebar.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_sidebar/private_sources_sidebar.tsx index 6cd7a10fc7ade..c8eaffbfbec10 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_sidebar/private_sources_sidebar.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_sidebar/private_sources_sidebar.tsx @@ -35,10 +35,10 @@ export const PrivateSourcesSidebar = () => { : PRIVATE_VIEW_ONLY_PAGE_DESCRIPTION; const { - contentSource: { id = '', name = '' }, + contentSource: { id = '' }, } = useValues(SourceLogic); - const navItems = [{ id, name, items: useSourceSubNav() }]; + const navItems = [{ id, name: '', items: useSourceSubNav() }]; return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts index 2cec9f617cd27..a43fb6f293457 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts @@ -253,12 +253,12 @@ export const SOURCE_OBJ_TYPES = { defaultMessage: 'Bugs', }), ISSUES: i18n.translate('xpack.enterpriseSearch.workplaceSearch.sources.objTypes.issues', { - defaultMessage: 'Issues', + defaultMessage: 'Issues (including comments)', }), PULL_REQUESTS: i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.sources.objTypes.pullRequests', { - defaultMessage: 'Pull Requests', + defaultMessage: 'Pull Requests (including comments)', } ), REPOSITORY_LIST: i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts index 691b52c9f51e4..ec515eed91179 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts @@ -45,10 +45,9 @@ export const CUSTOM_SOURCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-custom-ap export const CUSTOM_API_DOCS_URL = `${DOCS_PREFIX}/workplace-search-custom-sources-api.html`; export const CUSTOM_API_DOCUMENT_PERMISSIONS_DOCS_URL = `${CUSTOM_SOURCE_DOCS_URL}#custom-api-source-document-level-access-control`; export const ENT_SEARCH_LICENSE_MANAGEMENT = `${docLinks.enterpriseSearchBase}/license-management.html`; -export const SYNCHRONIZATION_DOCS_URL = '#TODO'; -export const DIFFERENT_SYNC_TYPES_DOCS_URL = '#TODO'; -export const SYNC_BEST_PRACTICES_DOCS_URL = '#TODO'; -export const OBJECTS_AND_ASSETS_DOCS_URL = '#TODO'; +export const SYNCHRONIZATION_DOCS_URL = `${DOCS_PREFIX}}/workplace-search-customizing-indexing-rules.html#workplace-search-customizing-indexing-rules`; +export const DIFFERENT_SYNC_TYPES_DOCS_URL = `${DOCS_PREFIX}}/workplace-search-customizing-indexing-rules.html#_indexing_schedule`; +export const OBJECTS_AND_ASSETS_DOCS_URL = `${DOCS_PREFIX}}/workplace-search-customizing-indexing-rules.html#workplace-search-customizing-indexing-rules`; export const PERSONAL_PATH = '/p'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts index f81672e71e013..ab45c54cc5c57 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { Moment } from 'moment'; - import { RoleMapping } from '../shared/types'; export * from '../../../common/types/workplace_search'; @@ -148,6 +146,8 @@ export interface IndexingSchedule extends SyncIndexItem<string> { blockedWindows?: BlockedWindow[]; } +export type TimeUnit = 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years'; + export type SyncJobType = 'full' | 'incremental' | 'delete' | 'permissions'; export const DAYS_OF_WEEK_VALUES = [ @@ -164,8 +164,8 @@ export type DayOfWeek = typeof DAYS_OF_WEEK_VALUES[number]; export interface BlockedWindow { jobType: SyncJobType; day: DayOfWeek | 'all'; - start: Moment; - end: Moment; + start: string; + end: string; } export interface IndexingConfig { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx index d99eac5de74e5..c9eb2e0afdf5e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx @@ -5,20 +5,21 @@ * 2.0. */ -import { setMockValues } from '../../../../__mocks__/kea_logic'; +import { setMockValues, setMockActions } from '../../../../__mocks__/kea_logic'; import { fullContentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; import { shallow } from 'enzyme'; -import { EuiEmptyPrompt, EuiPanel, EuiTable } from '@elastic/eui'; +import { EuiConfirmModal, EuiEmptyPrompt, EuiPanel, EuiTable } from '@elastic/eui'; import { ComponentLoader } from '../../../components/shared/component_loader'; import { Overview } from './overview'; describe('Overview', () => { + const initializeSourceSynchronization = jest.fn(); const contentSource = fullContentSources[0]; const dataLoading = false; const isOrganization = true; @@ -31,6 +32,7 @@ describe('Overview', () => { beforeEach(() => { setMockValues({ ...mockValues }); + setMockActions({ initializeSourceSynchronization }); }); it('renders', () => { @@ -118,4 +120,14 @@ describe('Overview', () => { expect(wrapper.find('[data-test-subj="DocumentPermissionsDisabled"]')).toHaveLength(1); }); + + it('handles confirmModal submission', () => { + const wrapper = shallow(<Overview />); + const button = wrapper.find('[data-test-subj="SyncButton"]'); + button.prop('onClick')!({} as any); + const modal = wrapper.find(EuiConfirmModal); + modal.prop('onConfirm')!({} as any); + + expect(initializeSourceSynchronization).toHaveBeenCalled(); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx index a4fe0329e6c42..9441f43dc253f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx @@ -5,11 +5,13 @@ * 2.0. */ -import React from 'react'; +import React, { useState } from 'react'; -import { useValues } from 'kea'; +import { useValues, useActions } from 'kea'; import { + EuiButton, + EuiConfirmModal, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, @@ -30,7 +32,8 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiListGroupItemTo } from '../../../../shared/react_router_helpers'; +import { CANCEL_BUTTON_LABEL, START_BUTTON_LABEL } from '../../../../shared/constants'; +import { EuiListGroupItemTo, EuiLinkTo } from '../../../../shared/react_router_helpers'; import { AppLogic } from '../../../app_logic'; import aclImage from '../../../assets/supports_acl.svg'; import { ComponentLoader } from '../../../components/shared/component_loader'; @@ -48,7 +51,10 @@ import { DOCUMENT_PERMISSIONS_DOCS_URL, ENT_SEARCH_LICENSE_MANAGEMENT, EXTERNAL_IDENTITIES_DOCS_URL, + SYNC_FREQUENCY_PATH, + BLOCKED_TIME_WINDOWS_PATH, getGroupPath, + getContentSourcePath, } from '../../../routes'; import { SOURCES_NO_CONTENT_TITLE, @@ -77,6 +83,12 @@ import { LEARN_CUSTOM_FEATURES_BUTTON, DOC_PERMISSIONS_DESCRIPTION, CUSTOM_CALLOUT_TITLE, + SOURCE_SYNCHRONIZATION_TITLE, + SOURCE_SYNC_FREQUENCY_LINK_LABEL, + SOURCE_BLOCKED_TIME_WINDOWS_LINK_LABEL, + SOURCE_SYNCHRONIZATION_BUTTON_LABEL, + SOURCE_SYNC_CONFIRM_TITLE, + SOURCE_SYNC_CONFIRM_MESSAGE, } from '../constants'; import { SourceLogic } from '../source_logic'; @@ -84,6 +96,7 @@ import { SourceLayout } from './source_layout'; export const Overview: React.FC = () => { const { contentSource } = useValues(SourceLogic); + const { initializeSourceSynchronization } = useActions(SourceLogic); const { isOrganization } = useValues(AppLogic); const { @@ -99,8 +112,21 @@ export const Overview: React.FC = () => { indexPermissions, hasPermissions, isFederatedSource, + isIndexedSource, } = contentSource; + const [isSyncing, setIsSyncing] = useState(false); + const [isModalVisible, setIsModalVisible] = useState(false); + const closeModal = () => setIsModalVisible(false); + const handleSyncClick = () => setIsModalVisible(true); + const showSyncTriggerCallout = !custom && isIndexedSource && isOrganization; + + const onSyncConfirm = () => { + initializeSourceSynchronization(id); + setIsSyncing(true); + closeModal(); + }; + const DocumentSummary = () => { let totalDocuments = 0; const tableContent = summary?.map((item, index) => { @@ -451,9 +477,57 @@ export const Overview: React.FC = () => { </EuiPanel> ); + const syncTriggerCallout = ( + <EuiFlexItem> + <EuiSpacer /> + <EuiTitle size="xs"> + <h5>{SOURCE_SYNCHRONIZATION_TITLE}</h5> + </EuiTitle> + <EuiSpacer size="s" /> + <EuiPanel color="subdued"> + <EuiButton fill isLoading={isSyncing} onClick={handleSyncClick} data-test-subj="SyncButton"> + {SOURCE_SYNCHRONIZATION_BUTTON_LABEL} + </EuiButton> + <EuiSpacer size="m" /> + <EuiText size="s"> + <FormattedMessage + id="xpack.enterpriseSearch.workplaceSearch.sources.synchronizationCallout" + defaultMessage="Configure {syncFrequencyLink} or {blockTimeWindowsLink}." + values={{ + syncFrequencyLink: ( + <EuiLinkTo to={getContentSourcePath(SYNC_FREQUENCY_PATH, id, isOrganization)}> + {SOURCE_SYNC_FREQUENCY_LINK_LABEL} + </EuiLinkTo> + ), + blockTimeWindowsLink: ( + <EuiLinkTo to={getContentSourcePath(BLOCKED_TIME_WINDOWS_PATH, id, isOrganization)}> + {SOURCE_BLOCKED_TIME_WINDOWS_LINK_LABEL} + </EuiLinkTo> + ), + }} + /> + </EuiText> + </EuiPanel> + </EuiFlexItem> + ); + + const syncConfirmModal = ( + <EuiConfirmModal + title={SOURCE_SYNC_CONFIRM_TITLE} + onCancel={closeModal} + onConfirm={onSyncConfirm} + cancelButtonText={CANCEL_BUTTON_LABEL} + confirmButtonText={START_BUTTON_LABEL} + defaultFocusedButton="confirm" + > + <p>{SOURCE_SYNC_CONFIRM_MESSAGE}</p> + </EuiConfirmModal> + ); + return ( <SourceLayout pageViewTelemetry="source_overview"> <ViewContentHeader title={SOURCE_OVERVIEW_TITLE} /> + {isModalVisible && syncConfirmModal} <EuiFlexGroup gutterSize="xl" alignItems="flexStart"> <EuiFlexItem grow={8}> @@ -513,6 +587,7 @@ export const Overview: React.FC = () => { )} </> )} + {showSyncTriggerCallout && syncTriggerCallout} </EuiFlexGroup> </EuiFlexItem> </EuiFlexGroup> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx index cae1e8834cdd2..99597023303ff 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx @@ -37,7 +37,7 @@ export const useSourceSubNav = () => { if (!id) return undefined; const isCustom = serviceType === CUSTOM_SERVICE_TYPE; - const showSynchronization = isIndexedSource && isOrganization; + const showSynchronization = isIndexedSource && isOrganization && !isCustom; const navItems: Array<EuiSideNavItemType<unknown>> = [ { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/__mocks__/syncronization.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/__mocks__/synchronization.mock.ts similarity index 75% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/__mocks__/syncronization.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/__mocks__/synchronization.mock.ts index a71be55339f48..af6a0552fc27b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/__mocks__/syncronization.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/__mocks__/synchronization.mock.ts @@ -5,13 +5,11 @@ * 2.0. */ -import moment from 'moment'; - import { SyncJobType, DayOfWeek } from '../../../../../types'; export const blockedWindow = { jobType: 'incremental' as SyncJobType, day: 'sunday' as DayOfWeek, - start: moment().set('hour', 11).set('minutes', 0), - end: moment().set('hour', 13).set('minutes', 0), + start: '11:00:00Z', + end: '13:00:00Z', }; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.test.tsx index 703b1f9d8c5fe..f3c01b8d94d37 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.test.tsx @@ -5,18 +5,44 @@ * 2.0. */ -import { blockedWindow } from './__mocks__/syncronization.mock'; +import '../../../../../__mocks__/shallow_useeffect.mock'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; +import { fullContentSources } from '../../../../__mocks__/content_sources.mock'; +import { blockedWindow } from './__mocks__/synchronization.mock'; import React from 'react'; import { shallow } from 'enzyme'; +import moment from 'moment'; -import { EuiDatePickerRange, EuiSelect, EuiSuperSelect } from '@elastic/eui'; +import { + EuiButton, + EuiDatePicker, + EuiDatePickerRange, + EuiSelect, + EuiSuperSelect, +} from '@elastic/eui'; import { BlockedWindowItem } from './blocked_window_item'; describe('BlockedWindowItem', () => { - const props = { blockedWindow }; + const removeBlockedWindow = jest.fn(); + const setBlockedTimeWindow = jest.fn(); + const mockActions = { + removeBlockedWindow, + setBlockedTimeWindow, + }; + const mockValues = { + contentSource: fullContentSources[0], + }; + + beforeEach(() => { + setMockActions(mockActions); + setMockValues(mockValues); + }); + + const props = { blockedWindow, index: 0 }; + it('renders', () => { const wrapper = shallow(<BlockedWindowItem {...props} />); @@ -24,4 +50,47 @@ describe('BlockedWindowItem', () => { expect(wrapper.find(EuiSuperSelect)).toHaveLength(1); expect(wrapper.find(EuiDatePickerRange)).toHaveLength(1); }); + + it('handles remove button click', () => { + const wrapper = shallow(<BlockedWindowItem {...props} />); + wrapper.find(EuiButton).simulate('click'); + + expect(removeBlockedWindow).toHaveBeenCalledWith(0); + }); + + it('handles "jobType" select change', () => { + const wrapper = shallow(<BlockedWindowItem {...props} />); + wrapper.find(EuiSuperSelect).simulate('change', 'delete'); + + expect(setBlockedTimeWindow).toHaveBeenCalledWith(0, 'jobType', 'delete'); + }); + + it('handles "day" select change', () => { + const wrapper = shallow(<BlockedWindowItem {...props} />); + wrapper.find(EuiSelect).simulate('change', { target: { value: 'tuesday' } }); + + expect(setBlockedTimeWindow).toHaveBeenCalledWith(0, 'day', 'tuesday'); + }); + + it('handles "start" time change', () => { + const wrapper = shallow(<BlockedWindowItem {...props} />); + const dayRange = wrapper.find(EuiDatePickerRange).dive(); + dayRange + .find(EuiDatePicker) + .first() + .simulate('change', moment().utc().set({ hour: 10, minute: 0, seconds: 0 })); + + expect(setBlockedTimeWindow).toHaveBeenCalledWith(0, 'start', '10:00:00Z'); + }); + + it('handles "end" time change', () => { + const wrapper = shallow(<BlockedWindowItem {...props} />); + const dayRange = wrapper.find(EuiDatePickerRange).dive(); + dayRange + .find(EuiDatePicker) + .last() + .simulate('change', moment().utc().set({ hour: 12, minute: 0, seconds: 0 })); + + expect(setBlockedTimeWindow).toHaveBeenCalledWith(0, 'end', '12:00:00Z'); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.tsx index 5aec23b5faaea..272efc6fc3c50 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_item.tsx @@ -7,6 +7,7 @@ import React from 'react'; +import { useActions, useValues } from 'kea'; import moment from 'moment'; import { @@ -40,8 +41,13 @@ import { UTC_TITLE, } from '../../constants'; +import { SourceLogic } from '../../source_logic'; + +import { SynchronizationLogic } from './synchronization_logic'; + interface Props { blockedWindow: BlockedWindow; + index: number; } const syncOptions = [ @@ -66,7 +72,7 @@ const syncOptions = [ ), }, { - value: 'deletion', + value: 'delete', inputDisplay: DELETION_SYNC_LABEL, dropdownDisplay: ( <> @@ -93,10 +99,11 @@ const daySelectOptions = DAYS_OF_WEEK_VALUES.map((day) => ({ })) as EuiSelectOption[]; daySelectOptions.push({ text: ALL_DAYS_LABEL, value: 'all' }); -export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow }) => { - const handleSyncTypeChange = () => '#TODO'; - const handleStartDateChange = () => '#TODO'; - const handleEndDateChange = () => '#TODO'; +export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow, index }) => { + const { contentSource } = useValues(SourceLogic); + const { removeBlockedWindow, setBlockedTimeWindow } = useActions( + SynchronizationLogic({ contentSource }) + ); return ( <> @@ -109,7 +116,7 @@ export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow }) => { <EuiSuperSelect valueOfSelected={blockedWindow.jobType} options={syncOptions} - onChange={handleSyncTypeChange} + onChange={(value) => setBlockedTimeWindow(index, 'jobType', value)} itemClassName="blockedWindowSelectItem" popoverClassName="blockedWindowSelectPopover" /> @@ -118,7 +125,11 @@ export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow }) => { <EuiText>{ON_LABEL}</EuiText> </EuiFlexItem> <EuiFlexItem style={{ minWidth: 130 }}> - <EuiSelect value={blockedWindow.day} options={daySelectOptions} /> + <EuiSelect + value={blockedWindow.day} + onChange={(e) => setBlockedTimeWindow(index, 'day', e.target.value)} + options={daySelectOptions} + /> </EuiFlexItem> <EuiFlexItem grow={false}> <EuiText>{BETWEEN_LABEL}</EuiText> @@ -129,8 +140,11 @@ export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow }) => { <EuiDatePicker showTimeSelect showTimeSelectOnly - selected={moment(blockedWindow.start, 'HH:mm:ssZ')} - onChange={handleStartDateChange} + selected={moment(blockedWindow.start, 'HH:mm:ssZ').utc()} + onChange={(value) => + value && + setBlockedTimeWindow(index, 'start', `${value.utc().format('HH:mm:ss')}Z`) + } dateFormat="h:mm A" timeFormat="h:mm A" /> @@ -139,8 +153,10 @@ export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow }) => { <EuiDatePicker showTimeSelect showTimeSelectOnly - selected={moment(blockedWindow.end, 'HH:mm:ssZ')} - onChange={handleEndDateChange} + selected={moment(blockedWindow.end, 'HH:mm:ssZ').utc()} + onChange={(value) => + value && setBlockedTimeWindow(index, 'end', `${value.utc().format('HH:mm:ss')}Z`) + } dateFormat="h:mm A" timeFormat="h:mm A" /> @@ -163,7 +179,7 @@ export const BlockedWindowItem: React.FC<Props> = ({ blockedWindow }) => { /> </EuiFlexItem> <EuiFlexItem grow={false}> - <EuiButton fill color="danger"> + <EuiButton fill color="danger" onClick={() => removeBlockedWindow(index)}> {REMOVE_BUTTON} </EuiButton> </EuiFlexItem> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.test.tsx index 7cada1d39fb6e..44973cef966ee 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.test.tsx @@ -8,7 +8,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import { fullContentSources } from '../../../../__mocks__/content_sources.mock'; -import { blockedWindow } from './__mocks__/syncronization.mock'; +import { blockedWindow } from './__mocks__/synchronization.mock'; import React from 'react'; @@ -24,9 +24,11 @@ describe('BlockedWindows', () => { const mockActions = { addBlockedWindow, }; + const contentSource = { ...fullContentSources[0] }; + contentSource.indexing.schedule.blockedWindows = [blockedWindow] as any; const mockValues = { - blockedWindows: [blockedWindow], - contentSource: fullContentSources[0], + contentSource, + schedule: contentSource.indexing.schedule, }; beforeEach(() => { @@ -41,7 +43,7 @@ describe('BlockedWindows', () => { }); it('renders empty state', () => { - setMockValues({ blockedWindows: [] }); + setMockValues({ schedule: { blockedWindows: [] } }); const wrapper = shallow(<BlockedWindows />); expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.tsx index f0227f76d4aa5..488346c2d6e30 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/blocked_window_tab.tsx @@ -20,10 +20,12 @@ import { SynchronizationLogic } from './synchronization_logic'; export const BlockedWindows: React.FC = () => { const { contentSource } = useValues(SourceLogic); - const { blockedWindows } = useValues(SynchronizationLogic({ contentSource })); + const { + schedule: { blockedWindows }, + } = useValues(SynchronizationLogic({ contentSource })); const { addBlockedWindow } = useActions(SynchronizationLogic({ contentSource })); - const hasBlockedWindows = blockedWindows.length > 0; + const hasBlockedWindows = blockedWindows && blockedWindows.length > 0; const emptyState = ( <> @@ -43,8 +45,8 @@ export const BlockedWindows: React.FC = () => { const blockedWindowItems = ( <> - {blockedWindows.map((blockedWindow, i) => ( - <BlockedWindowItem key={i} blockedWindow={blockedWindow} /> + {blockedWindows?.map((blockedWindow, i) => ( + <BlockedWindowItem key={i} index={i} blockedWindow={blockedWindow} /> ))} <EuiSpacer /> <EuiButton onClick={addBlockedWindow}>{ADD_LABEL}</EuiButton> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx index 914ec9dfe6eff..a682e10269e6c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx @@ -21,15 +21,16 @@ import { } from '@elastic/eui'; import { SAVE_BUTTON_LABEL } from '../../../../../shared/constants'; +import { UnsavedChangesPrompt } from '../../../../../shared/unsaved_changes_prompt'; import { ViewContentHeader } from '../../../../components/shared/view_content_header'; import { NAV, RESET_BUTTON } from '../../../../constants'; -import { DIFFERENT_SYNC_TYPES_DOCS_URL, SYNC_BEST_PRACTICES_DOCS_URL } from '../../../../routes'; +import { DIFFERENT_SYNC_TYPES_DOCS_URL } from '../../../../routes'; import { SOURCE_FREQUENCY_DESCRIPTION, SOURCE_SYNC_FREQUENCY_TITLE, BLOCKED_TIME_WINDOWS_TITLE, - DIFFERENT_SYNC_TYPES_LINK_LABEL, - SYNC_BEST_PRACTICES_LINK_LABEL, + SYNC_FREQUENCY_LINK_LABEL, + SYNC_UNSAVED_CHANGES_MESSAGE, } from '../../constants'; import { SourceLogic } from '../../source_logic'; import { SourceLayout } from '../source_layout'; @@ -44,7 +45,12 @@ interface FrequencyProps { export const Frequency: React.FC<FrequencyProps> = ({ tabId }) => { const { contentSource } = useValues(SourceLogic); - const { handleSelectedTabChanged } = useActions(SynchronizationLogic({ contentSource })); + const { hasUnsavedFrequencyChanges, navigatingBetweenTabs } = useValues( + SynchronizationLogic({ contentSource }) + ); + const { handleSelectedTabChanged, resetSyncSettings, updateFrequencySettings } = useActions( + SynchronizationLogic({ contentSource }) + ); const tabs = [ { @@ -66,10 +72,14 @@ export const Frequency: React.FC<FrequencyProps> = ({ tabId }) => { const actions = ( <EuiFlexGroup> <EuiFlexItem> - <EuiButtonEmpty>{RESET_BUTTON}</EuiButtonEmpty>{' '} + <EuiButtonEmpty onClick={resetSyncSettings} disabled={!hasUnsavedFrequencyChanges}> + {RESET_BUTTON} + </EuiButtonEmpty> </EuiFlexItem> <EuiFlexItem> - <EuiButton fill>{SAVE_BUTTON_LABEL}</EuiButton>{' '} + <EuiButton fill onClick={updateFrequencySettings} disabled={!hasUnsavedFrequencyChanges}> + {SAVE_BUTTON_LABEL} + </EuiButton> </EuiFlexItem> </EuiFlexGroup> ); @@ -78,12 +88,7 @@ export const Frequency: React.FC<FrequencyProps> = ({ tabId }) => { <EuiFlexGroup> <EuiFlexItem grow={false}> <EuiLink href={DIFFERENT_SYNC_TYPES_DOCS_URL} external> - {DIFFERENT_SYNC_TYPES_LINK_LABEL} - </EuiLink> - </EuiFlexItem> - <EuiFlexItem grow={false}> - <EuiLink href={SYNC_BEST_PRACTICES_DOCS_URL} external> - {SYNC_BEST_PRACTICES_LINK_LABEL} + {SYNC_FREQUENCY_LINK_LABEL} </EuiLink> </EuiFlexItem> </EuiFlexGroup> @@ -98,6 +103,10 @@ export const Frequency: React.FC<FrequencyProps> = ({ tabId }) => { pageViewTelemetry="source_synchronization_frequency" isLoading={false} > + <UnsavedChangesPrompt + hasUnsavedChanges={!navigatingBetweenTabs && hasUnsavedFrequencyChanges} + messageText={SYNC_UNSAVED_CHANGES_MESSAGE} + /> <ViewContentHeader title={NAV.SYNCHRONIZATION_FREQUENCY} description={SOURCE_FREQUENCY_DESCRIPTION} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.test.tsx index b3421539cb7ba..7498a185a80ec 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.test.tsx @@ -5,6 +5,10 @@ * 2.0. */ +import '../../../../../__mocks__/shallow_useeffect.mock'; +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; +import { fullContentSources } from '../../../../__mocks__/content_sources.mock'; + import React from 'react'; import { shallow } from 'enzyme'; @@ -12,9 +16,24 @@ import moment from 'moment'; import { EuiFieldNumber } from '@elastic/eui'; +import { SyncJobType } from '../../../../types'; + import { FrequencyItem } from './frequency_item'; describe('FrequencyItem', () => { + const setSyncFrequency = jest.fn(); + const mockActions = { + setSyncFrequency, + }; + const mockValues = { + contentSource: fullContentSources[0], + }; + + beforeEach(() => { + setMockActions(mockActions); + setMockValues(mockValues); + }); + const estimate = { duration: 'PT3D', nextStart: '2021-09-27T21:39:24+00:00', @@ -22,6 +41,7 @@ describe('FrequencyItem', () => { }; const props = { + type: 'full' as SyncJobType, label: 'Item', description: 'My item', duration: 'PT2D', @@ -73,4 +93,33 @@ describe('FrequencyItem', () => { ).toEqual('in 2 days'); }); }); + + describe('onChange handlers', () => { + it('calls setSyncFrequency for "days"', () => { + const wrapper = shallow(<FrequencyItem {...props} />); + wrapper + .find('[data-test-subj="durationDays"]') + .simulate('change', { target: { value: '3' } }); + + expect(setSyncFrequency).toHaveBeenCalledWith('full', '3', 'days'); + }); + + it('calls setSyncFrequency for "hours"', () => { + const wrapper = shallow(<FrequencyItem {...props} />); + wrapper + .find('[data-test-subj="durationHours"]') + .simulate('change', { target: { value: '3' } }); + + expect(setSyncFrequency).toHaveBeenCalledWith('full', '3', 'hours'); + }); + + it('calls setSyncFrequency for "minutes"', () => { + const wrapper = shallow(<FrequencyItem {...props} />); + wrapper + .find('[data-test-subj="durationMinutes"]') + .simulate('change', { target: { value: '3' } }); + + expect(setSyncFrequency).toHaveBeenCalledWith('full', '3', 'minutes'); + }); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.tsx index 618f5c73d6099..a51500e3076a8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency_item.tsx @@ -7,6 +7,7 @@ import React from 'react'; +import { useActions, useValues } from 'kea'; import moment from 'moment'; import { @@ -24,18 +25,30 @@ import { HOURS_UNIT_LABEL, DAYS_UNIT_LABEL, } from '../../../../../shared/constants'; -import { SyncEstimate } from '../../../../types'; +import { SyncEstimate, SyncJobType } from '../../../../types'; import { NEXT_SYNC_RUNNING_MESSAGE } from '../../constants'; +import { SourceLogic } from '../../source_logic'; + +import { SynchronizationLogic } from './synchronization_logic'; interface Props { + type: SyncJobType; label: string; description: string; duration: string; estimate: SyncEstimate; } -export const FrequencyItem: React.FC<Props> = ({ label, description, duration, estimate }) => { +export const FrequencyItem: React.FC<Props> = ({ + type, + label, + description, + duration, + estimate, +}) => { + const { contentSource } = useValues(SourceLogic); + const { setSyncFrequency } = useActions(SynchronizationLogic({ contentSource })); const { lastRun, nextStart, duration: durationEstimate } = estimate; const estimateDisplay = durationEstimate && moment.duration(durationEstimate).humanize(); const nextStartIsPast = moment().isAfter(nextStart); @@ -107,6 +120,7 @@ export const FrequencyItem: React.FC<Props> = ({ label, description, duration, e data-test-subj="durationDays" value={moment.duration(duration).days()} append={DAYS_UNIT_LABEL} + onChange={(e) => setSyncFrequency(type, e.target.value, 'days')} /> </EuiFlexItem> <EuiFlexItem grow={false} style={{ width: 120 }}> @@ -114,6 +128,7 @@ export const FrequencyItem: React.FC<Props> = ({ label, description, duration, e data-test-subj="durationHours" value={moment.duration(duration).hours()} append={HOURS_UNIT_LABEL} + onChange={(e) => setSyncFrequency(type, e.target.value, 'hours')} /> </EuiFlexItem> <EuiFlexItem grow={false} style={{ width: 150 }}> @@ -121,6 +136,7 @@ export const FrequencyItem: React.FC<Props> = ({ label, description, duration, e data-test-subj="durationMinutes" value={moment.duration(duration).minutes()} append={MINUTES_UNIT_LABEL} + onChange={(e) => setSyncFrequency(type, e.target.value, 'minutes')} /> </EuiFlexItem> <EuiFlexItem grow={false}> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.test.tsx index 42a08084db418..13dc2872037c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.test.tsx @@ -8,7 +8,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock'; import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; import { fullContentSources } from '../../../../__mocks__/content_sources.mock'; -import { blockedWindow } from './__mocks__/syncronization.mock'; +import { blockedWindow } from './__mocks__/synchronization.mock'; import React from 'react'; @@ -21,14 +21,14 @@ import { ObjectsAndAssets } from './objects_and_assets'; describe('ObjectsAndAssets', () => { const setThumbnailsChecked = jest.fn(); const setContentExtractionChecked = jest.fn(); - const updateSyncSettings = jest.fn(); + const updateObjectsAndAssetsSettings = jest.fn(); const resetSyncSettings = jest.fn(); const contentSource = fullContentSources[0]; const mockActions = { setThumbnailsChecked, setContentExtractionChecked, - updateSyncSettings, + updateObjectsAndAssetsSettings, resetSyncSettings, }; const mockValues = { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx index 98abdb8bf67ea..54ce0563ddeb3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx @@ -31,7 +31,7 @@ import { SYNC_MANAGEMENT_THUMBNAILS_LABEL, SYNC_MANAGEMENT_THUMBNAILS_GLOBAL_CONFIG_LABEL, SOURCE_OBJECTS_AND_ASSETS_DESCRIPTION, - SYNC_OBJECTS_TYPES_LINK_LABEL, + OBJECTS_AND_ASSETS_LINK_LABEL, SOURCE_OBJECTS_AND_ASSETS_LABEL, SYNC_UNSAVED_CHANGES_MESSAGE, } from '../../constants'; @@ -47,7 +47,7 @@ export const ObjectsAndAssets: React.FC = () => { const { setThumbnailsChecked, setContentExtractionChecked, - updateSyncSettings, + updateObjectsAndAssetsSettings, resetSyncSettings, } = useActions(SynchronizationLogic({ contentSource })); @@ -61,7 +61,11 @@ export const ObjectsAndAssets: React.FC = () => { </EuiButtonEmpty> </EuiFlexItem> <EuiFlexItem> - <EuiButton fill onClick={updateSyncSettings} disabled={!hasUnsavedObjectsAndAssetsChanges}> + <EuiButton + fill + onClick={updateObjectsAndAssetsSettings} + disabled={!hasUnsavedObjectsAndAssetsChanges} + > {SAVE_BUTTON_LABEL} </EuiButton> </EuiFlexItem> @@ -84,7 +88,7 @@ export const ObjectsAndAssets: React.FC = () => { action={actions} /> <EuiLink href={OBJECTS_AND_ASSETS_DOCS_URL} external> - {SYNC_OBJECTS_TYPES_LINK_LABEL} + {OBJECTS_AND_ASSETS_LINK_LABEL} </EuiLink> <EuiHorizontalRule /> <EuiText size="m">{SOURCE_OBJECTS_AND_ASSETS_LABEL}</EuiText> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.test.tsx index 6c382b0addab8..c85f2df1adb03 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.test.tsx @@ -22,9 +22,12 @@ describe('SyncFrequency', () => { const sourceWithNoDLP = cloneDeep(contentSource); sourceWithNoDLP.indexing.schedule.permissions = undefined as any; sourceWithNoDLP.indexing.schedule.estimates.permissions = undefined as any; + const { + indexing: { schedule }, + } = contentSource; it('renders with DLP', () => { - setMockValues({ contentSource }); + setMockValues({ contentSource, schedule }); const wrapper = shallow(<SyncFrequency />); expect(wrapper.find(FrequencyItem)).toHaveLength(4); @@ -32,7 +35,7 @@ describe('SyncFrequency', () => { it('renders without DLP', () => { setMockValues({ - contentSource: sourceWithNoDLP, + schedule: sourceWithNoDLP.indexing.schedule, }); const wrapper = shallow(<SyncFrequency />); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.tsx index 2a0ccb1fdb2c9..4e79f22977855 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/sync_frequency_tab.tsx @@ -24,31 +24,30 @@ import { import { SourceLogic } from '../../source_logic'; import { FrequencyItem } from './frequency_item'; +import { SynchronizationLogic } from './synchronization_logic'; export const SyncFrequency: React.FC = () => { + const { contentSource } = useValues(SourceLogic); const { - contentSource: { - indexing: { - schedule: { - full: fullDuration, - incremental: incrementalDuration, - delete: deleteDuration, - permissions: permissionsDuration, - estimates: { - full: fullEstimate, - incremental: incrementalEstimate, - delete: deleteEstimate, - permissions: permissionsEstimate, - }, - }, + schedule: { + full: fullDuration, + incremental: incrementalDuration, + delete: deleteDuration, + permissions: permissionsDuration, + estimates: { + full: fullEstimate, + incremental: incrementalEstimate, + delete: deleteEstimate, + permissions: permissionsEstimate, }, }, - } = useValues(SourceLogic); + } = useValues(SynchronizationLogic({ contentSource })); return ( <> <EuiSpacer /> <FrequencyItem + type="full" label={FULL_SYNC_LABEL} description={FULL_SYNC_DESCRIPTION} duration={fullDuration} @@ -56,6 +55,7 @@ export const SyncFrequency: React.FC = () => { /> <EuiHorizontalRule /> <FrequencyItem + type="incremental" label={INCREMENTAL_SYNC_LABEL} description={INCREMENTAL_SYNC_DESCRIPTION} duration={incrementalDuration} @@ -63,6 +63,7 @@ export const SyncFrequency: React.FC = () => { /> <EuiHorizontalRule /> <FrequencyItem + type="delete" label={DELETION_SYNC_LABEL} description={DELETION_SYNC_DESCRIPTION} duration={deleteDuration} @@ -72,6 +73,7 @@ export const SyncFrequency: React.FC = () => { <> <EuiHorizontalRule /> <FrequencyItem + type="permissions" label={PERMISSIONS_SYNC_LABEL} description={PERMISSIONS_SYNC_DESCRIPTION} duration={permissionsDuration} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx index 21c44225615ea..e88d4d251fa54 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx @@ -15,11 +15,11 @@ import { ViewContentHeader } from '../../../../components/shared/view_content_he import { NAV } from '../../../../constants'; import { SYNCHRONIZATION_DOCS_URL } from '../../../../routes'; import { - SOURCE_SYNCRONIZATION_DESCRIPTION, + SOURCE_SYNCHRONIZATION_DESCRIPTION, SYNCHRONIZATION_DISABLED_TITLE, SYNCHRONIZATION_DISABLED_DESCRIPTION, - SOURCE_SYNCRONIZATION_TOGGLE_LABEL, - SOURCE_SYNCRONIZATION_TOGGLE_DESCRIPTION, + SOURCE_SYNCHRONIZATION_TOGGLE_LABEL, + SOURCE_SYNCHRONIZATION_TOGGLE_DESCRIPTION, SYNCHRONIZATION_LINK_LABEL, } from '../../constants'; import { SourceLogic } from '../../source_logic'; @@ -40,13 +40,13 @@ export const Synchronization: React.FC = () => { const syncToggle = ( <EuiPanel hasBorder> <EuiSwitch - label={SOURCE_SYNCRONIZATION_TOGGLE_LABEL} + label={SOURCE_SYNCHRONIZATION_TOGGLE_LABEL} checked={enabled} onChange={(e) => onChange(e.target.checked)} /> <EuiSpacer size="m" /> <EuiText size="s" color="subdued"> - {SOURCE_SYNCRONIZATION_TOGGLE_DESCRIPTION} + {SOURCE_SYNCHRONIZATION_TOGGLE_DESCRIPTION} </EuiText> </EuiPanel> ); @@ -65,7 +65,7 @@ export const Synchronization: React.FC = () => { > <ViewContentHeader title={NAV.SYNCHRONIZATION} - description={SOURCE_SYNCRONIZATION_DESCRIPTION} + description={SOURCE_SYNCHRONIZATION_DESCRIPTION} /> <EuiLink href={SYNCHRONIZATION_DOCS_URL} external> {SYNCHRONIZATION_LINK_LABEL} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.test.ts index 298c315f4cf90..25fb256e85f01 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.test.ts @@ -38,14 +38,23 @@ describe('SynchronizationLogic', () => { const { navigateToUrl } = mockKibanaValues; const { mount } = new LogicMounter(SynchronizationLogic); const contentSource = fullContentSources[0]; + const sourceWithNoBlockedWindows = { + ...contentSource, + indexing: { + ...contentSource.indexing, + schedule: { + ...contentSource.indexing.schedule, + blockedWindows: undefined, + }, + }, + }; const defaultValues = { navigatingBetweenTabs: false, hasUnsavedObjectsAndAssetsChanges: false, - hasUnsavedFrequencyChanges: true, + hasUnsavedFrequencyChanges: false, contentExtractionChecked: true, thumbnailsChecked: true, - blockedWindows: [], schedule: contentSource.indexing.schedule, cachedSchedule: contentSource.indexing.schedule, }; @@ -66,10 +75,23 @@ describe('SynchronizationLogic', () => { expect(SynchronizationLogic.values.navigatingBetweenTabs).toEqual(true); }); - it('addBlockedWindow', () => { - SynchronizationLogic.actions.addBlockedWindow(); + describe('addBlockedWindow', () => { + it('creates and populates empty array when undefined', () => { + mount({}, { contentSource: sourceWithNoBlockedWindows }); + SynchronizationLogic.actions.addBlockedWindow(); + + expect(SynchronizationLogic.values.schedule.blockedWindows).toEqual([emptyBlockedWindow]); + }); - expect(SynchronizationLogic.values.blockedWindows).toEqual([emptyBlockedWindow]); + it('adds item when list has items', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.addBlockedWindow(); + + expect(SynchronizationLogic.values.schedule.blockedWindows).toEqual([ + emptyBlockedWindow, + emptyBlockedWindow, + ]); + }); }); it('setThumbnailsChecked', () => { @@ -83,6 +105,84 @@ describe('SynchronizationLogic', () => { expect(SynchronizationLogic.values.contentExtractionChecked).toEqual(false); }); + + it('resetSyncSettings', () => { + SynchronizationLogic.actions.setContentExtractionChecked(false); + SynchronizationLogic.actions.setThumbnailsChecked(false); + SynchronizationLogic.actions.resetSyncSettings(); + + expect(SynchronizationLogic.values.thumbnailsChecked).toEqual(true); + expect(SynchronizationLogic.values.contentExtractionChecked).toEqual(true); + }); + + describe('setSyncFrequency', () => { + it('sets "days"', () => { + SynchronizationLogic.actions.setSyncFrequency('full', '1', 'days'); + + expect(SynchronizationLogic.values.schedule.full).toEqual('P1D'); + }); + + it('sets "hours"', () => { + SynchronizationLogic.actions.setSyncFrequency('full', '10', 'hours'); + + expect(SynchronizationLogic.values.schedule.full).toEqual('P1DT10H'); + }); + + it('sets "minutes"', () => { + SynchronizationLogic.actions.setSyncFrequency('full', '30', 'minutes'); + + expect(SynchronizationLogic.values.schedule.full).toEqual('P1DT30M'); + }); + }); + + describe('removeBlockedWindow', () => { + it('removes window', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.removeBlockedWindow(0); + + expect(SynchronizationLogic.values.schedule.blockedWindows).toEqual([emptyBlockedWindow]); + }); + + it('returns "undefined" when last window removed', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.removeBlockedWindow(0); + + expect(SynchronizationLogic.values.schedule.blockedWindows).toBeUndefined(); + }); + }); + }); + + describe('setBlockedTimeWindow', () => { + it('sets "jobType"', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.setBlockedTimeWindow(0, 'jobType', 'incremental'); + + expect(SynchronizationLogic.values.schedule.blockedWindows![0].jobType).toEqual( + 'incremental' + ); + }); + + it('sets "day"', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.setBlockedTimeWindow(0, 'day', 'tuesday'); + + expect(SynchronizationLogic.values.schedule.blockedWindows![0].day).toEqual('tuesday'); + }); + + it('sets "start"', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.setBlockedTimeWindow(0, 'start', '9:00:00Z'); + + expect(SynchronizationLogic.values.schedule.blockedWindows![0].start).toEqual('9:00:00Z'); + }); + + it('sets "end"', () => { + SynchronizationLogic.actions.addBlockedWindow(); + SynchronizationLogic.actions.setBlockedTimeWindow(0, 'end', '11:00:00Z'); + + expect(SynchronizationLogic.values.schedule.blockedWindows![0].end).toEqual('11:00:00Z'); + }); }); describe('listeners', () => { @@ -110,103 +210,121 @@ describe('SynchronizationLogic', () => { }); describe('updateSyncEnabled', () => { - it('calls API and sets values for false value', async () => { - const setContentSourceSpy = jest.spyOn(SourceLogic.actions, 'setContentSource'); - const promise = Promise.resolve(contentSource); - http.patch.mockReturnValue(promise); + it('calls updateServerSettings method', async () => { + const updateServerSettingsSpy = jest.spyOn( + SynchronizationLogic.actions, + 'updateServerSettings' + ); SynchronizationLogic.actions.updateSyncEnabled(false); - expect(http.patch).toHaveBeenCalledWith( - '/internal/workplace_search/org/sources/123/settings', - { - body: JSON.stringify({ - content_source: { - indexing: { enabled: false }, - }, - }), - } - ); - await promise; - expect(setContentSourceSpy).toHaveBeenCalledWith(contentSource); - expect(flashSuccessToast).toHaveBeenCalledWith('Source synchronization disabled.'); + expect(updateServerSettingsSpy).toHaveBeenCalledWith({ + content_source: { + indexing: { enabled: false }, + }, + }); }); + }); - it('calls API and sets values for true value', async () => { - const promise = Promise.resolve(contentSource); - http.patch.mockReturnValue(promise); - SynchronizationLogic.actions.updateSyncEnabled(true); - - expect(http.patch).toHaveBeenCalledWith( - '/internal/workplace_search/org/sources/123/settings', - { - body: JSON.stringify({ - content_source: { - indexing: { enabled: true }, - }, - }), - } + describe('updateObjectsAndAssetsSettings', () => { + it('calls updateServerSettings method', async () => { + const updateServerSettingsSpy = jest.spyOn( + SynchronizationLogic.actions, + 'updateServerSettings' ); - await promise; - expect(flashSuccessToast).toHaveBeenCalledWith('Source synchronization enabled.'); - }); - - it('handles error', async () => { - const error = { - response: { - error: 'this is an error', - status: 400, + SynchronizationLogic.actions.updateObjectsAndAssetsSettings(); + + expect(updateServerSettingsSpy).toHaveBeenCalledWith({ + content_source: { + indexing: { + features: { + content_extraction: { enabled: true }, + thumbnails: { enabled: true }, + }, + }, }, - }; - const promise = Promise.reject(error); - http.patch.mockReturnValue(promise); - SynchronizationLogic.actions.updateSyncEnabled(false); - await expectedAsyncError(promise); - - expect(flashAPIErrors).toHaveBeenCalledWith(error); + }); }); }); - describe('resetSyncSettings', () => { - it('calls methods', async () => { - const setThumbnailsCheckedSpy = jest.spyOn( + describe('updateFrequencySettings', () => { + it('calls updateServerSettings method', async () => { + SynchronizationLogic.actions.addBlockedWindow(); + const updateServerSettingsSpy = jest.spyOn( SynchronizationLogic.actions, - 'setThumbnailsChecked' + 'updateServerSettings' ); - const setContentExtractionCheckedSpy = jest.spyOn( + SynchronizationLogic.actions.updateFrequencySettings(); + + expect(updateServerSettingsSpy).toHaveBeenCalledWith({ + content_source: { + indexing: { + schedule: { + full: 'P1D', + incremental: 'PT2H', + delete: 'PT10M', + blocked_windows: [ + { + day: 'monday', + end: '13:00:00Z', + job_type: 'full', + start: '11:00:00Z', + }, + ], + }, + }, + }, + }); + }); + + it('handles case where blockedWindows undefined', async () => { + const updateServerSettingsSpy = jest.spyOn( SynchronizationLogic.actions, - 'setContentExtractionChecked' + 'updateServerSettings' ); - SynchronizationLogic.actions.resetSyncSettings(); - - expect(setThumbnailsCheckedSpy).toHaveBeenCalledWith(true); - expect(setContentExtractionCheckedSpy).toHaveBeenCalledWith(true); + SynchronizationLogic.actions.updateFrequencySettings(); + + expect(updateServerSettingsSpy).toHaveBeenCalledWith({ + content_source: { + indexing: { + schedule: { + full: 'P1D', + incremental: 'PT2H', + delete: 'PT10M', + blocked_windows: [], + }, + }, + }, + }); }); }); - describe('updateSyncSettings', () => { + describe('updateServerSettings', () => { + const body = { + content_source: { + indexing: { + features: { + content_extraction: { enabled: true }, + thumbnails: { enabled: true }, + }, + }, + }, + }; it('calls API and sets values', async () => { const setContentSourceSpy = jest.spyOn(SourceLogic.actions, 'setContentSource'); + const setServerScheduleSpy = jest.spyOn(SynchronizationLogic.actions, 'setServerSchedule'); const promise = Promise.resolve(contentSource); http.patch.mockReturnValue(promise); - SynchronizationLogic.actions.updateSyncSettings(); + SynchronizationLogic.actions.updateServerSettings(body); expect(http.patch).toHaveBeenCalledWith( '/internal/workplace_search/org/sources/123/settings', { - body: JSON.stringify({ - content_source: { - indexing: { - features: { - content_extraction: { enabled: true }, - thumbnails: { enabled: true }, - }, - }, - }, - }), + body: JSON.stringify(body), } ); await promise; expect(setContentSourceSpy).toHaveBeenCalledWith(contentSource); + expect(setServerScheduleSpy).toHaveBeenCalledWith(contentSource.indexing.schedule); expect(flashSuccessToast).toHaveBeenCalledWith('Source synchronization settings updated.'); }); @@ -219,7 +337,7 @@ describe('SynchronizationLogic', () => { }; const promise = Promise.reject(error); http.patch.mockReturnValue(promise); - SynchronizationLogic.actions.updateSyncSettings(); + SynchronizationLogic.actions.updateServerSettings(body); await expectedAsyncError(promise); expect(flashAPIErrors).toHaveBeenCalledWith(error); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.ts index 3aaa7f5fdfbf3..87a55f0e7dd3a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization_logic.ts @@ -20,24 +20,72 @@ import { BLOCKED_TIME_WINDOWS_PATH, getContentSourcePath, } from '../../../../routes'; -import { BlockedWindow, IndexingSchedule } from '../../../../types'; - import { - SYNC_ENABLED_MESSAGE, - SYNC_DISABLED_MESSAGE, - SYNC_SETTINGS_UPDATED_MESSAGE, -} from '../../constants'; + BlockedWindow, + DayOfWeek, + IndexingSchedule, + SyncJobType, + TimeUnit, +} from '../../../../types'; + +import { SYNC_SETTINGS_UPDATED_MESSAGE } from '../../constants'; import { SourceLogic } from '../../source_logic'; +type BlockedWindowPropType = 'jobType' | 'day' | 'start' | 'end'; + +interface ServerBlockedWindow { + job_type: string; + day: string; + start: string; + end: string; +} + +interface ServerSyncSettingsBody { + content_source: { + indexing: { + enabled?: boolean; + features?: { + content_extraction: { enabled: boolean }; + thumbnails: { enabled: boolean }; + }; + schedule?: { + full: string; + incremental: string; + delete: string; + permissions?: string; + blocked_windows?: ServerBlockedWindow[]; + }; + }; + }; +} + interface SynchronizationActions { setNavigatingBetweenTabs(navigatingBetweenTabs: boolean): boolean; handleSelectedTabChanged(tabId: TabId): TabId; addBlockedWindow(): void; - updateSyncSettings(): void; + removeBlockedWindow(index: number): number; + updateFrequencySettings(): void; + updateObjectsAndAssetsSettings(): void; resetSyncSettings(): void; updateSyncEnabled(enabled: boolean): boolean; setThumbnailsChecked(checked: boolean): boolean; + setSyncFrequency( + type: SyncJobType, + value: string, + unit: TimeUnit + ): { type: SyncJobType; value: number; unit: TimeUnit }; + setBlockedTimeWindow( + index: number, + prop: BlockedWindowPropType, + value: string + ): { + index: number; + prop: BlockedWindowPropType; + value: string; + }; setContentExtractionChecked(checked: boolean): boolean; + setServerSchedule(schedule: IndexingSchedule): IndexingSchedule; + updateServerSettings(body: ServerSyncSettingsBody): ServerSyncSettingsBody; } interface SynchronizationValues { @@ -46,7 +94,6 @@ interface SynchronizationValues { hasUnsavedObjectsAndAssetsChanges: boolean; thumbnailsChecked: boolean; contentExtractionChecked: boolean; - blockedWindows: BlockedWindow[]; cachedSchedule: IndexingSchedule; schedule: IndexingSchedule; } @@ -54,8 +101,12 @@ interface SynchronizationValues { export const emptyBlockedWindow: BlockedWindow = { jobType: 'full', day: 'monday', - start: moment().set('hour', 11).set('minutes', 0), - end: moment().set('hour', 13).set('minutes', 0), + start: '11:00:00Z', + end: '13:00:00Z', +}; + +type BlockedWindowMap = { + [prop in keyof BlockedWindow]: SyncJobType | DayOfWeek | 'all' | string; }; export const SynchronizationLogic = kea< @@ -67,8 +118,22 @@ export const SynchronizationLogic = kea< handleSelectedTabChanged: (tabId: TabId) => tabId, updateSyncEnabled: (enabled: boolean) => enabled, setThumbnailsChecked: (checked: boolean) => checked, + setSyncFrequency: (type: SyncJobType, value: string, unit: TimeUnit) => ({ + type, + value, + unit, + }), + setBlockedTimeWindow: (index: number, prop: BlockedWindowPropType, value: string) => ({ + index, + prop, + value, + }), setContentExtractionChecked: (checked: boolean) => checked, - updateSyncSettings: true, + updateServerSettings: (body: ServerSyncSettingsBody) => body, + setServerSchedule: (schedule: IndexingSchedule) => schedule, + removeBlockedWindow: (index: number) => index, + updateFrequencySettings: true, + updateObjectsAndAssetsSettings: true, resetSyncSettings: true, addBlockedWindow: true, }, @@ -79,26 +144,88 @@ export const SynchronizationLogic = kea< setNavigatingBetweenTabs: (_, navigatingBetweenTabs) => navigatingBetweenTabs, }, ], - blockedWindows: [ - props.contentSource.indexing.schedule.blockedWindows || [], - { - addBlockedWindow: (state, _) => [...state, emptyBlockedWindow], - }, - ], thumbnailsChecked: [ props.contentSource.indexing.features.thumbnails.enabled, { setThumbnailsChecked: (_, thumbnailsChecked) => thumbnailsChecked, + resetSyncSettings: () => props.contentSource.indexing.features.thumbnails.enabled, }, ], contentExtractionChecked: [ props.contentSource.indexing.features.contentExtraction.enabled, { setContentExtractionChecked: (_, contentExtractionChecked) => contentExtractionChecked, + resetSyncSettings: () => props.contentSource.indexing.features.contentExtraction.enabled, + }, + ], + cachedSchedule: [ + stripScheduleSeconds(props.contentSource.indexing.schedule), + { + setServerSchedule: (_, schedule) => schedule, + }, + ], + schedule: [ + stripScheduleSeconds(props.contentSource.indexing.schedule), + { + resetSyncSettings: () => stripScheduleSeconds(props.contentSource.indexing.schedule), + setServerSchedule: (_, schedule) => schedule, + setSyncFrequency: (state, { type, value, unit }) => { + let currentValue; + const schedule = cloneDeep(state); + const duration = schedule[type]; + + switch (unit) { + case 'days': + currentValue = moment.duration(duration).days(); + break; + case 'hours': + currentValue = moment.duration(duration).hours(); + break; + default: + currentValue = moment.duration(duration).minutes(); + break; + } + + // momentJS doesn't seem to have a way to simply set the minutes/hours/days, so we have + // to subtract the current value and then add the new value. + // https://momentjs.com/docs/#/durations/ + schedule[type] = moment + .duration(duration) + .subtract(currentValue, unit) + .add(value, unit) + .toISOString(); + + return schedule; + }, + addBlockedWindow: (state, _) => { + const schedule = cloneDeep(state); + const blockedWindows = schedule.blockedWindows || []; + blockedWindows.push(emptyBlockedWindow); + schedule.blockedWindows = blockedWindows; + return schedule; + }, + removeBlockedWindow: (state, index) => { + const schedule = cloneDeep(state); + const blockedWindows = schedule.blockedWindows; + blockedWindows!.splice(index, 1); + if (blockedWindows!.length > 0) { + schedule.blockedWindows = blockedWindows; + } else { + delete schedule.blockedWindows; + } + return schedule; + }, + setBlockedTimeWindow: (state, { index, prop, value }) => { + const schedule = cloneDeep(state); + const blockedWindows = schedule.blockedWindows; + const blockedWindow = blockedWindows![index] as BlockedWindowMap; + blockedWindow[prop] = value; + (blockedWindows![index] as BlockedWindowMap) = blockedWindow; + schedule.blockedWindows = blockedWindows; + return schedule; + }, }, ], - cachedSchedule: [stripScheduleSeconds(props.contentSource.indexing.schedule)], - schedule: [stripScheduleSeconds(props.contentSource.indexing.schedule)], }), selectors: ({ selectors }) => ({ hasUnsavedObjectsAndAssetsChanges: [ @@ -125,7 +252,7 @@ export const SynchronizationLogic = kea< ], hasUnsavedFrequencyChanges: [ () => [selectors.cachedSchedule, selectors.schedule], - (cachedSchedule, schedule) => isEqual(cachedSchedule, schedule), + (cachedSchedule, schedule) => !isEqual(cachedSchedule, schedule), ], }), listeners: ({ actions, values, props }) => ({ @@ -149,46 +276,49 @@ export const SynchronizationLogic = kea< actions.setNavigatingBetweenTabs(false); }, updateSyncEnabled: async (enabled) => { - const { id: sourceId } = props.contentSource; - const route = `/internal/workplace_search/org/sources/${sourceId}/settings`; - const successMessage = enabled ? SYNC_ENABLED_MESSAGE : SYNC_DISABLED_MESSAGE; - - try { - const response = await HttpLogic.values.http.patch(route, { - body: JSON.stringify({ content_source: { indexing: { enabled } } }), - }); - - SourceLogic.actions.setContentSource(response); - flashSuccessToast(successMessage); - } catch (e) { - flashAPIErrors(e); - } + actions.updateServerSettings({ + content_source: { + indexing: { enabled }, + }, + }); + }, + updateObjectsAndAssetsSettings: () => { + actions.updateServerSettings({ + content_source: { + indexing: { + features: { + content_extraction: { enabled: values.contentExtractionChecked }, + thumbnails: { enabled: values.thumbnailsChecked }, + }, + }, + }, + }); }, - resetSyncSettings: () => { - actions.setThumbnailsChecked(props.contentSource.indexing.features.thumbnails.enabled); - actions.setContentExtractionChecked( - props.contentSource.indexing.features.contentExtraction.enabled - ); + updateFrequencySettings: () => { + actions.updateServerSettings({ + content_source: { + indexing: { + schedule: { + full: values.schedule.full, + incremental: values.schedule.incremental, + delete: values.schedule.delete, + blocked_windows: formatBlockedWindowsForServer(values.schedule.blockedWindows), + }, + }, + }, + }); }, - updateSyncSettings: async () => { + updateServerSettings: async (body: ServerSyncSettingsBody) => { const { id: sourceId } = props.contentSource; const route = `/internal/workplace_search/org/sources/${sourceId}/settings`; try { const response = await HttpLogic.values.http.patch(route, { - body: JSON.stringify({ - content_source: { - indexing: { - features: { - content_extraction: { enabled: values.contentExtractionChecked }, - thumbnails: { enabled: values.thumbnailsChecked }, - }, - }, - }, - }), + body: JSON.stringify(body), }); SourceLogic.actions.setContentSource(response); + SynchronizationLogic.actions.setServerSchedule(response.indexing.schedule); flashSuccessToast(SYNC_SETTINGS_UPDATED_MESSAGE); } catch (e) { flashAPIErrors(e); @@ -215,3 +345,16 @@ export const stripScheduleSeconds = (schedule: IndexingSchedule): IndexingSchedu return _schedule; }; + +const formatBlockedWindowsForServer = ( + blockedWindows?: BlockedWindow[] +): ServerBlockedWindow[] | undefined => { + if (!blockedWindows || blockedWindows.length < 1) return []; + + return blockedWindows.map(({ jobType, day, start, end }) => ({ + job_type: jobType, + day, + start, + end, + })); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts index 1f76d667949fb..f44dbae0608ea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts @@ -527,11 +527,11 @@ export const SOURCE_OVERVIEW_TITLE = i18n.translate( } ); -export const SOURCE_SYNCRONIZATION_DESCRIPTION = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncronizationDescription', +export const SOURCE_SYNCHRONIZATION_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationDescription', { defaultMessage: - 'DO NOT TRANSLATE, temporary placeholder: Sync chupa chups dragée gummi bears jelly beans brownie. Fruitcake pie chocolate cake caramels carrot cake cotton candy dragée sweet roll soufflé.', + 'Synchronization provides control over data being indexed from the content source. Enable synchronization of data from the content source to Workplace Search.', } ); @@ -539,7 +539,7 @@ export const SOURCE_FREQUENCY_DESCRIPTION = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.sources.sourceFrequencyDescription', { defaultMessage: - 'DO NOT TRANSLATE, temporary placeholder: Frequency chupa chups dragée gummi bears jelly beans brownie. Fruitcake pie chocolate cake caramels carrot cake cotton candy dragée sweet roll soufflé.', + 'Schedule the frequency of data synchronization between Workplace search and the content source. Indexing schedules that occur less frequently lower the burden on third-party servers, while more frequent will ensure your data is up-to-date.', } ); @@ -547,7 +547,7 @@ export const SOURCE_OBJECTS_AND_ASSETS_DESCRIPTION = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.sources.sourceObjectsAndAssetsDescription', { defaultMessage: - 'DO NOT TRANSLATE, temporary placeholder: Objects chupa chups dragée gummi bears jelly beans brownie. Fruitcake pie chocolate cake caramels carrot cake cotton candy dragée sweet roll soufflé.', + 'Customize the indexing rules that determine what data is synchronized from this content source to Workplace Search.', } ); @@ -558,24 +558,67 @@ export const SOURCE_OBJECTS_AND_ASSETS_LABEL = i18n.translate( } ); -export const SOURCE_SYNCRONIZATION_TOGGLE_LABEL = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncronizationToggleLabel', +export const SOURCE_SYNCHRONIZATION_TOGGLE_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationToggleLabel', { defaultMessage: 'Synchronize this source', } ); -export const SOURCE_SYNCRONIZATION_TOGGLE_DESCRIPTION = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncronizationToggleDescription', +export const SOURCE_SYNCHRONIZATION_TOGGLE_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationToggleDescription', { defaultMessage: 'Source content will automatically be kept in sync.', } ); -export const SOURCE_SYNCRONIZATION_FREQUENCY_TITLE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncronizationFrequencyTitle', +export const SOURCE_SYNCHRONIZATION_FREQUENCY_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationFrequencyTitle', { - defaultMessage: 'Syncronization frequency', + defaultMessage: 'Synchronization frequency', + } +); + +export const SOURCE_SYNCHRONIZATION_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationTitle', + { + defaultMessage: 'Synchronization', + } +); + +export const SOURCE_SYNCHRONIZATION_BUTTON_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationButtonLabel', + { + defaultMessage: 'Synchronize content', + } +); + +export const SOURCE_SYNC_FREQUENCY_LINK_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncFrequencyLinkLabel', + { + defaultMessage: 'sync frequency', + } +); + +export const SOURCE_BLOCKED_TIME_WINDOWS_LINK_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceBlockedTimeWindowsLinkLabel', + { + defaultMessage: 'blocked time windows', + } +); + +export const SOURCE_SYNC_CONFIRM_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncConfirmTitle', + { + defaultMessage: 'Start new content sync?', + } +); + +export const SOURCE_SYNC_CONFIRM_MESSAGE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.sourceSyncConfirmMessage', + { + defaultMessage: + 'Are you sure you would like to continue with this request and stop all other syncs?', } ); @@ -614,24 +657,17 @@ export const SYNCHRONIZATION_DISABLED_DESCRIPTION = i18n.translate( } ); -export const DIFFERENT_SYNC_TYPES_LINK_LABEL = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.differentSyncTypesLinkLabel', - { - defaultMessage: 'Learn more about different sync types', - } -); - -export const SYNC_BEST_PRACTICES_LINK_LABEL = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.syncBestPracticesLinkLabel', +export const SYNC_FREQUENCY_LINK_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.syncFrequencyLinkLabel', { - defaultMessage: 'Learn more about sync best practices', + defaultMessage: 'Learn more about synchronization frequency', } ); -export const SYNC_OBJECTS_TYPES_LINK_LABEL = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.syncObjectsTypesLinkLabel', +export const OBJECTS_AND_ASSETS_LINK_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.objectsAndAssetsLinkLabel', { - defaultMessage: 'Learn more about sync objects types', + defaultMessage: 'Learn more about Objects and assets', } ); @@ -705,20 +741,6 @@ export const BLOCKED_EMPTY_STATE_DESCRIPTION = i18n.translate( } ); -export const SYNC_ENABLED_MESSAGE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.syncEnabledMessage', - { - defaultMessage: 'Source synchronization enabled.', - } -); - -export const SYNC_DISABLED_MESSAGE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sources.syncDisabledMessage', - { - defaultMessage: 'Source synchronization disabled.', - } -); - export const SYNC_SETTINGS_UPDATED_MESSAGE = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.sources.syncSettingsUpdatedMessage', { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts index 1fb4477cea5c0..fb88360de5df0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts @@ -429,6 +429,34 @@ describe('SourceLogic', () => { }); }); + describe('initializeSourceSynchronization', () => { + it('calls API and fetches fresh source state', async () => { + const initializeSourceSpy = jest.spyOn(SourceLogic.actions, 'initializeSource'); + const promise = Promise.resolve(contentSource); + http.post.mockReturnValue(promise); + SourceLogic.actions.initializeSourceSynchronization(contentSource.id); + + expect(http.post).toHaveBeenCalledWith('/internal/workplace_search/org/sources/123/sync'); + await promise; + expect(initializeSourceSpy).toHaveBeenCalledWith(contentSource.id); + }); + + it('handles error', async () => { + const error = { + response: { + error: 'this is an error', + status: 400, + }, + }; + const promise = Promise.reject(error); + http.post.mockReturnValue(promise); + SourceLogic.actions.initializeSourceSynchronization(contentSource.id); + await expectedAsyncError(promise); + + expect(flashAPIErrors).toHaveBeenCalledWith(error); + }); + }); + it('resetSourceState', () => { SourceLogic.actions.resetSourceState(); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index d10400bc5ba2d..9dcd0824cad11 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -27,6 +27,7 @@ export interface SourceActions { onUpdateSourceName(name: string): string; setSearchResults(searchResultsResponse: SearchResultsResponse): SearchResultsResponse; initializeFederatedSummary(sourceId: string): { sourceId: string }; + initializeSourceSynchronization(sourceId: string): { sourceId: string }; onUpdateSummary(summary: DocumentSummaryItem[]): DocumentSummaryItem[]; setContentFilterValue(contentFilterValue: string): string; setActivePage(activePage: number): number; @@ -81,6 +82,7 @@ export const SourceLogic = kea<MakeLogicType<SourceValues, SourceActions>>({ setActivePage: (activePage: number) => activePage, initializeSource: (sourceId: string) => ({ sourceId }), initializeFederatedSummary: (sourceId: string) => ({ sourceId }), + initializeSourceSynchronization: (sourceId: string) => ({ sourceId }), searchContentSourceDocuments: (sourceId: string) => ({ sourceId }), updateContentSource: (sourceId: string, source: SourceUpdatePayload) => ({ sourceId, source }), removeContentSource: (sourceId: string) => ({ @@ -254,6 +256,15 @@ export const SourceLogic = kea<MakeLogicType<SourceValues, SourceActions>>({ actions.setButtonNotLoading(); } }, + initializeSourceSynchronization: async ({ sourceId }) => { + const route = `/internal/workplace_search/org/sources/${sourceId}/sync`; + try { + await HttpLogic.values.http.post(route); + actions.initializeSource(sourceId); + } catch (e) { + flashAPIErrors(e); + } + }, onUpdateSourceName: (name: string) => { flashSuccessToast( i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx index a971df8f89914..997d79f67cb13 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx @@ -75,9 +75,6 @@ export const Security: React.FC = () => { }; const headerActions = [ - <EuiButtonEmpty disabled={!unsavedChanges || dataLoading} onClick={resetState}> - {RESET_BUTTON} - </EuiButtonEmpty>, <EuiButton disabled={!hasPlatinumLicense || !unsavedChanges || dataLoading} onClick={showConfirmModal} @@ -86,6 +83,9 @@ export const Security: React.FC = () => { > {SAVE_SETTINGS_BUTTON} </EuiButton>, + <EuiButtonEmpty disabled={!unsavedChanges || dataLoading} onClick={resetState}> + {RESET_BUTTON} + </EuiButtonEmpty>, ]; const allSourcesToggle = ( diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts index 706bc8a4853a7..961635c3f9001 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts @@ -42,6 +42,7 @@ import { registerOrgSourceDownloadDiagnosticsRoute, registerOrgSourceOauthConfigurationsRoute, registerOrgSourceOauthConfigurationRoute, + registerOrgSourceSynchronizeRoute, registerOauthConnectorParamsRoute, } from './sources'; @@ -1252,6 +1253,29 @@ describe('sources routes', () => { }); }); + describe('POST /internal/workplace_search/org/sources/{id}/sync', () => { + let mockRouter: MockRouter; + + beforeEach(() => { + jest.clearAllMocks(); + mockRouter = new MockRouter({ + method: 'post', + path: '/internal/workplace_search/org/sources/{id}/sync', + }); + + registerOrgSourceSynchronizeRoute({ + ...mockDependencies, + router: mockRouter.router, + }); + }); + + it('creates a request handler', () => { + expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ + path: '/ws/org/sources/:id/sync', + }); + }); + }); + describe('GET /internal/workplace_search/sources/create', () => { const tokenPackage = 'some_encrypted_secrets'; diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts index 69a6470b5b9ce..011fe341d6edf 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts @@ -79,6 +79,10 @@ const sourceSettingsSchema = schema.object({ ), schedule: schema.maybe( schema.object({ + full: schema.maybe(schema.string()), + incremental: schema.maybe(schema.string()), + delete: schema.maybe(schema.string()), + permissions: schema.maybe(schema.string()), blocked_windows: schema.maybe( schema.arrayOf( schema.object({ @@ -887,6 +891,25 @@ export function registerOrgSourceOauthConfigurationRoute({ ); } +export function registerOrgSourceSynchronizeRoute({ + router, + enterpriseSearchRequestHandler, +}: RouteDependencies) { + router.post( + { + path: '/internal/workplace_search/org/sources/{id}/sync', + validate: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + enterpriseSearchRequestHandler.createRequest({ + path: '/ws/org/sources/:id/sync', + }) + ); +} + // Same route is used for org and account. `state` passes the context. export function registerOauthConnectorParamsRoute({ router, @@ -952,5 +975,6 @@ export const registerSourcesRoutes = (dependencies: RouteDependencies) => { registerOrgSourceDownloadDiagnosticsRoute(dependencies); registerOrgSourceOauthConfigurationsRoute(dependencies); registerOrgSourceOauthConfigurationRoute(dependencies); + registerOrgSourceSynchronizeRoute(dependencies); registerOauthConnectorParamsRoute(dependencies); }; diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index e482db6ae73ab..131cc276fc073 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -13,6 +13,8 @@ export const FLEET_SYSTEM_PACKAGE = 'system'; export const FLEET_ELASTIC_AGENT_PACKAGE = 'elastic_agent'; export const FLEET_SERVER_PACKAGE = 'fleet_server'; export const FLEET_ENDPOINT_PACKAGE = 'endpoint'; +export const FLEET_APM_PACKAGE = 'apm'; +export const FLEET_SYNTHETICS_PACKAGE = 'synthetics'; /* Package rules: @@ -37,7 +39,11 @@ export const unremovablePackages = [ export const defaultPackages = unremovablePackages.filter((p) => p !== FLEET_ENDPOINT_PACKAGE); -export const autoUpdatePackages = [FLEET_ENDPOINT_PACKAGE]; +export const autoUpdatePackages = [ + FLEET_ENDPOINT_PACKAGE, + FLEET_APM_PACKAGE, + FLEET_SYNTHETICS_PACKAGE, +]; export const agentAssetTypes = { Input: 'input', diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index a487fd0a37e70..df4cdec184dc8 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -227,6 +227,7 @@ export type RegistrySearchResult = Pick< | 'internal' | 'data_streams' | 'policy_templates' + | 'categories' >; export type ScreenshotItem = RegistryImage | PackageSpecScreenshot; @@ -376,6 +377,7 @@ export interface IntegrationCardItem { icons: Array<PackageSpecIcon | CustomIntegrationIcon>; integration: string; id: string; + categories: string[]; } export type PackagesGroupedByStatus = Record<ValueOf<InstallationStatus>, PackageList>; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts b/x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts index a637f19423a6b..198aa111c6fb0 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts @@ -13,6 +13,7 @@ export interface PostFleetSetupResponse { export interface GetFleetStatusResponse { isReady: boolean; missing_requirements: Array< + | 'security_required' | 'tls_required' | 'api_keys' | 'fleet_admin_user' diff --git a/x-pack/plugins/fleet/kibana.json b/x-pack/plugins/fleet/kibana.json index c4782156b1982..9de538ee91b8c 100644 --- a/x-pack/plugins/fleet/kibana.json +++ b/x-pack/plugins/fleet/kibana.json @@ -8,7 +8,7 @@ "server": true, "ui": true, "configPath": ["xpack", "fleet"], - "requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations"], + "requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations", "share"], "optionalPlugins": ["security", "features", "cloud", "usageCollection", "home", "globalSearch"], "extraPublicDirs": ["common"], "requiredBundles": ["kibanaReact", "esUiShared", "home", "infra", "kibanaUtils"] diff --git a/x-pack/plugins/fleet/public/applications/fleet/app.tsx b/x-pack/plugins/fleet/public/applications/fleet/app.tsx index 11be87f146851..682c889d80b97 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/app.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/app.tsx @@ -45,6 +45,7 @@ import { DefaultLayout, DefaultPageTitle, WithoutHeaderLayout, WithHeaderLayout import { AgentPolicyApp } from './sections/agent_policy'; import { DataStreamApp } from './sections/data_stream'; import { AgentsApp } from './sections/agents'; +import { MissingESRequirementsPage } from './sections/agents/agent_requirements_page'; import { CreatePackagePolicyPage } from './sections/agent_policy/create_package_policy_page'; import { EnrollmentTokenListPage } from './sections/agents/enrollment_token_list_page'; @@ -71,6 +72,53 @@ const Panel = styled(EuiPanel)` margin-left: auto; `; +const PermissionsError: React.FunctionComponent<{ error: string }> = memo(({ error }) => { + if (error === 'MISSING_SECURITY') { + return <MissingESRequirementsPage missingRequirements={['security_required', 'api_keys']} />; + } + + if (error === 'MISSING_SUPERUSER_ROLE') { + return ( + <Panel> + <EuiEmptyPrompt + iconType="securityApp" + title={ + <h2> + <FormattedMessage + id="xpack.fleet.permissionDeniedErrorTitle" + defaultMessage="Permission denied" + /> + </h2> + } + body={ + <p> + <FormattedMessage + id="xpack.fleet.permissionDeniedErrorMessage" + defaultMessage="You are not authorized to access Fleet. Fleet requires {roleName} privileges." + values={{ roleName: <EuiCode>superuser</EuiCode> }} + /> + </p> + } + /> + </Panel> + ); + } + + return ( + <Error + title={ + <FormattedMessage + id="xpack.fleet.permissionsRequestErrorMessageTitle" + defaultMessage="Unable to check permissions" + /> + } + error={i18n.translate('xpack.fleet.permissionsRequestErrorMessageDescription', { + defaultMessage: 'There was a problem checking Fleet permissions', + })} + /> + ); +}); + export const WithPermissionsAndSetup: React.FC = memo(({ children }) => { useBreadcrumbs('base'); const { notifications } = useStartServices(); @@ -121,58 +169,7 @@ export const WithPermissionsAndSetup: React.FC = memo(({ children }) => { if (isPermissionsLoading || permissionsError) { return ( <ErrorLayout isAddIntegrationsPath={isAddIntegrationsPath}> - {isPermissionsLoading ? ( - <Loading /> - ) : permissionsError === 'REQUEST_ERROR' ? ( - <Error - title={ - <FormattedMessage - id="xpack.fleet.permissionsRequestErrorMessageTitle" - defaultMessage="Unable to check permissions" - /> - } - error={i18n.translate('xpack.fleet.permissionsRequestErrorMessageDescription', { - defaultMessage: 'There was a problem checking Fleet permissions', - })} - /> - ) : ( - <Panel> - <EuiEmptyPrompt - iconType="securityApp" - title={ - <h2> - {permissionsError === 'MISSING_SUPERUSER_ROLE' ? ( - <FormattedMessage - id="xpack.fleet.permissionDeniedErrorTitle" - defaultMessage="Permission denied" - /> - ) : ( - <FormattedMessage - id="xpack.fleet.securityRequiredErrorTitle" - defaultMessage="Security is not enabled" - /> - )} - </h2> - } - body={ - <p> - {permissionsError === 'MISSING_SUPERUSER_ROLE' ? ( - <FormattedMessage - id="xpack.fleet.permissionDeniedErrorMessage" - defaultMessage="You are not authorized to access Fleet. Fleet requires {roleName} privileges." - values={{ roleName: <EuiCode>superuser</EuiCode> }} - /> - ) : ( - <FormattedMessage - id="xpack.fleet.securityRequiredErrorMessage" - defaultMessage="You must enable security in Kibana and Elasticsearch to use Fleet." - /> - )} - </p> - } - /> - </Panel> - )} + {isPermissionsLoading ? <Loading /> : <PermissionsError error={permissionsError!} />} </ErrorLayout> ); } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_configure_package.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_configure_package.tsx index 1ff5d20baec06..390e540f1b10f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_configure_package.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_configure_package.tsx @@ -49,7 +49,6 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{ ); // Configure inputs (and their streams) - // Assume packages only export one config template for now const renderConfigureInputs = () => packagePolicyTemplates.length ? ( <> diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/index.tsx index eec7d80b75c4b..c1d0e089fcc65 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/index.tsx @@ -10,17 +10,19 @@ import { Redirect, useRouteMatch, Switch, Route, useHistory, useLocation } from import { i18n } from '@kbn/i18n'; import { FormattedMessage, FormattedDate } from '@kbn/i18n/react'; import { + EuiButtonEmpty, + EuiDescriptionList, + EuiDescriptionListDescription, + EuiDescriptionListTitle, EuiFlexGroup, EuiFlexItem, + EuiI18nNumber, EuiIconTip, - EuiTitle, - EuiText, + EuiLink, + EuiPortal, EuiSpacer, - EuiButtonEmpty, - EuiI18nNumber, - EuiDescriptionList, - EuiDescriptionListTitle, - EuiDescriptionListDescription, + EuiText, + EuiTitle, } from '@elastic/eui'; import type { Props as EuiTabProps } from '@elastic/eui/src/components/tabs/tab'; import styled from 'styled-components'; @@ -36,7 +38,7 @@ import { useFleetStatus, useIntraAppState, } from '../../../hooks'; -import { Loading, Error } from '../../../components'; +import { Loading, Error, AgentEnrollmentFlyout, AddAgentHelpPopover } from '../../../components'; import { WithHeaderLayout } from '../../../layouts'; import { LinkedAgentCount, AgentPolicyActionMenu } from '../components'; @@ -58,7 +60,16 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { const agentPolicyRequest = useGetOneAgentPolicy(policyId); const agentPolicy = agentPolicyRequest.data ? agentPolicyRequest.data.item : null; const { isLoading, error, sendRequest: refreshAgentPolicy } = agentPolicyRequest; + const queryParams = new URLSearchParams(useLocation().search); + const openEnrollmentFlyoutOpenByDefault = queryParams.get('openEnrollmentFlyout') === 'true'; + const openAddAgentHelpPopoverOpenByDefault = queryParams.get('showAddAgentHelp') === 'true'; const [redirectToAgentPolicyList] = useState<boolean>(false); + const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState<boolean>( + openEnrollmentFlyoutOpenByDefault + ); + const [isAddAgentHelpPopoverOpen, setIsAddAgentHelpPopoverOpen] = useState<boolean>( + openAddAgentHelpPopoverOpenByDefault + ); const agentStatusRequest = useGetAgentStatus(policyId); const { refreshAgentStatus } = agentStatusRequest; const { @@ -66,8 +77,7 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { } = useStartServices(); const routeState = useIntraAppState<AgentPolicyDetailsDeployAgentAction>(); const agentStatus = agentStatusRequest.data?.results; - const queryParams = new URLSearchParams(useLocation().search); - const openEnrollmentFlyoutOpenByDefault = queryParams.get('openEnrollmentFlyout') === 'true'; + const { isReady: isFleetReady } = useFleetStatus(); const headerLeftContent = useMemo( @@ -138,6 +148,25 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { [getHref, isLoading, agentPolicy, policyId] ); + const onCancelEnrollment = useMemo(() => { + if (routeState && routeState.onDoneNavigateTo && isFleetReady) { + const [appId, options] = routeState.onDoneNavigateTo; + return () => navigateToApp(appId, options); + } + + return undefined; + }, [isFleetReady, navigateToApp, routeState]); + + const addAgentLink = ( + <EuiLink + onClick={() => { + setIsAddAgentHelpPopoverOpen(false); + setIsEnrollmentFlyoutOpen(true); + }} + > + <FormattedMessage id="xpack.fleet.policyDetails.addAgentButton" defaultMessage="Add agent" /> + </EuiLink> + ); const headerRightContent = useMemo( () => agentPolicy ? ( @@ -168,15 +197,25 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { { isDivider: true }, { label: i18n.translate('xpack.fleet.policyDetails.summary.usedBy', { - defaultMessage: 'Used by', + defaultMessage: 'Agents', }), - content: ( - <LinkedAgentCount - count={(agentStatus && agentStatus.total) || 0} - agentPolicyId={(agentPolicy && agentPolicy.id) || ''} - showAgentText - /> - ), + content: + agentStatus && agentStatus!.total ? ( + <LinkedAgentCount + count={agentStatus.total} + agentPolicyId={(agentPolicy && agentPolicy.id) || ''} + showAgentText + /> + ) : ( + <AddAgentHelpPopover + button={addAgentLink} + isOpen={isAddAgentHelpPopoverOpen} + offset={15} + closePopover={() => { + setIsAddAgentHelpPopoverOpen(false); + }} + /> + ), }, { isDivider: true }, { @@ -203,16 +242,7 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { onCopySuccess={(newAgentPolicy: AgentPolicy) => { history.push(getPath('policy_details', { policyId: newAgentPolicy.id })); }} - enrollmentFlyoutOpenByDefault={openEnrollmentFlyoutOpenByDefault} - onCancelEnrollment={ - routeState && routeState.onDoneNavigateTo && isFleetReady - ? () => - navigateToApp( - routeState.onDoneNavigateTo![0], - routeState.onDoneNavigateTo![1] - ) - : undefined - } + onCancelEnrollment={onCancelEnrollment} /> ), }, @@ -237,7 +267,7 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { </EuiFlexGroup> ) : undefined, /* eslint-disable-next-line react-hooks/exhaustive-deps */ - [agentPolicy, policyId, agentStatus] + [agentPolicy, policyId, agentStatus, isAddAgentHelpPopoverOpen] ); const headerTabs = useMemo(() => { @@ -303,8 +333,28 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => { ); } - return <AgentPolicyDetailsContent agentPolicy={agentPolicy} />; - }, [agentPolicy, policyId, error, isLoading, redirectToAgentPolicyList]); + return ( + <> + {isEnrollmentFlyoutOpen && ( + <EuiPortal> + <AgentEnrollmentFlyout + agentPolicy={agentPolicy} + onClose={onCancelEnrollment || (() => setIsEnrollmentFlyoutOpen(false))} + /> + </EuiPortal> + )} + <AgentPolicyDetailsContent agentPolicy={agentPolicy} /> + </> + ); + }, [ + redirectToAgentPolicyList, + isLoading, + error, + agentPolicy, + isEnrollmentFlyoutOpen, + onCancelEnrollment, + policyId, + ]); return ( <AgentPolicyRefreshContext.Provider value={{ refresh: refreshAgentPolicy }}> diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx index 9c5ec12645c1d..5aff449a923b3 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx @@ -76,7 +76,7 @@ export const MissingESRequirementsPage: React.FunctionComponent<{ values={{ esConfigFile: <EuiCode>elasticsearch.yml</EuiCode> }} /> <EuiSpacer size="l" /> - <RequirementItem isMissing={false}> + <RequirementItem isMissing={missingRequirements.includes('security_required')}> <FormattedMessage id="xpack.fleet.setupPage.elasticsearchSecurityFlagText" defaultMessage="{esSecurityLink}. Set {securityFlag} to {true} ." diff --git a/x-pack/plugins/fleet/public/applications/integrations/app.tsx b/x-pack/plugins/fleet/public/applications/integrations/app.tsx index b10cef9d3ffe4..c2f6f53627e38 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/app.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/app.tsx @@ -7,12 +7,10 @@ import React, { memo, useEffect, useState } from 'react'; import type { AppMountParameters } from 'kibana/public'; -import { EuiCode, EuiEmptyPrompt, EuiErrorBoundary, EuiPanel, EuiPortal } from '@elastic/eui'; +import { EuiErrorBoundary, EuiPortal } from '@elastic/eui'; import type { History } from 'history'; import { Router, Redirect, Route, Switch } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import styled from 'styled-components'; import useObservable from 'react-use/lib/useObservable'; import { @@ -42,6 +40,7 @@ import { EPMApp } from './sections/epm'; import { DefaultLayout } from './layouts'; import { PackageInstallProvider } from './hooks'; import { useBreadcrumbs, UIExtensionsContext } from './hooks'; +import { IntegrationsHeader } from './components/header'; const ErrorLayout = ({ children }: { children: JSX.Element }) => ( <EuiErrorBoundary> @@ -49,29 +48,23 @@ const ErrorLayout = ({ children }: { children: JSX.Element }) => ( </EuiErrorBoundary> ); -const Panel = styled(EuiPanel)` - max-width: 500px; - margin-right: auto; - margin-left: auto; -`; - export const WithPermissionsAndSetup: React.FC = memo(({ children }) => { useBreadcrumbs('integrations'); const [isPermissionsLoading, setIsPermissionsLoading] = useState<boolean>(false); - const [permissionsError, setPermissionsError] = useState<string>(); const [isInitialized, setIsInitialized] = useState(false); const [initializationError, setInitializationError] = useState<Error | null>(null); useEffect(() => { (async () => { - setPermissionsError(undefined); setIsInitialized(false); setInitializationError(null); try { + // Attempt Fleet Setup if user has permissions, otherwise skip setIsPermissionsLoading(true); const permissionsResponse = await sendGetPermissionsCheck(); setIsPermissionsLoading(false); + if (permissionsResponse.data?.success) { try { const setupResponse = await sendSetup(); @@ -83,69 +76,20 @@ export const WithPermissionsAndSetup: React.FC = memo(({ children }) => { } setIsInitialized(true); } else { - setPermissionsError(permissionsResponse.data?.error || 'REQUEST_ERROR'); + setIsInitialized(true); } - } catch (err) { - setPermissionsError('REQUEST_ERROR'); + } catch { + // If there's an error checking permissions, default to proceeding without running setup + // User will only have access to EPM endpoints if they actually have permission + setIsInitialized(true); } })(); }, []); - if (isPermissionsLoading || permissionsError) { + if (isPermissionsLoading) { return ( <ErrorLayout> - {isPermissionsLoading ? ( - <Loading /> - ) : permissionsError === 'REQUEST_ERROR' ? ( - <Error - title={ - <FormattedMessage - id="xpack.fleet.permissionsRequestErrorMessageTitle" - defaultMessage="Unable to check permissions" - /> - } - error={i18n.translate('xpack.fleet.permissionsRequestErrorMessageDescription', { - defaultMessage: 'There was a problem checking Fleet permissions', - })} - /> - ) : ( - <Panel> - <EuiEmptyPrompt - iconType="securityApp" - title={ - <h2> - {permissionsError === 'MISSING_SUPERUSER_ROLE' ? ( - <FormattedMessage - id="xpack.fleet.permissionDeniedErrorTitle" - defaultMessage="Permission denied" - /> - ) : ( - <FormattedMessage - id="xpack.fleet.securityRequiredErrorTitle" - defaultMessage="Security is not enabled" - /> - )} - </h2> - } - body={ - <p> - {permissionsError === 'MISSING_SUPERUSER_ROLE' ? ( - <FormattedMessage - id="xpack.fleet.integrationsPermissionDeniedErrorMessage" - defaultMessage="You are not authorized to access Integrations. Integrations requires {roleName} privileges." - values={{ roleName: <EuiCode>superuser</EuiCode> }} - /> - ) : ( - <FormattedMessage - id="xpack.fleet.integrationsSecurityRequiredErrorMessage" - defaultMessage="You must enable security in Kibana and Elasticsearch to use Integrations." - /> - )} - </p> - } - /> - </Panel> - )} + <Loading /> </ErrorLayout> ); } @@ -184,41 +128,53 @@ export const IntegrationsAppContext: React.FC<{ history: AppMountParameters['history']; kibanaVersion: string; extensions: UIExtensionsStorage; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; /** For testing purposes only */ routerHistory?: History<any>; // TODO remove -}> = memo(({ children, startServices, config, history, kibanaVersion, extensions }) => { - const isDarkMode = useObservable<boolean>(startServices.uiSettings.get$('theme:darkMode')); +}> = memo( + ({ + children, + startServices, + config, + history, + kibanaVersion, + extensions, + setHeaderActionMenu, + }) => { + const isDarkMode = useObservable<boolean>(startServices.uiSettings.get$('theme:darkMode')); - return ( - <RedirectAppLinks application={startServices.application}> - <startServices.i18n.Context> - <KibanaContextProvider services={{ ...startServices }}> - <EuiErrorBoundary> - <ConfigContext.Provider value={config}> - <KibanaVersionContext.Provider value={kibanaVersion}> - <EuiThemeProvider darkMode={isDarkMode}> - <UIExtensionsContext.Provider value={extensions}> - <FleetStatusProvider> - <startServices.customIntegrations.ContextProvider> - <Router history={history}> - <AgentPolicyContextProvider> - <PackageInstallProvider notifications={startServices.notifications}> - {children} - </PackageInstallProvider> - </AgentPolicyContextProvider> - </Router> - </startServices.customIntegrations.ContextProvider> - </FleetStatusProvider> - </UIExtensionsContext.Provider> - </EuiThemeProvider> - </KibanaVersionContext.Provider> - </ConfigContext.Provider> - </EuiErrorBoundary> - </KibanaContextProvider> - </startServices.i18n.Context> - </RedirectAppLinks> - ); -}); + return ( + <RedirectAppLinks application={startServices.application}> + <startServices.i18n.Context> + <KibanaContextProvider services={{ ...startServices }}> + <EuiErrorBoundary> + <ConfigContext.Provider value={config}> + <KibanaVersionContext.Provider value={kibanaVersion}> + <EuiThemeProvider darkMode={isDarkMode}> + <UIExtensionsContext.Provider value={extensions}> + <FleetStatusProvider> + <startServices.customIntegrations.ContextProvider> + <Router history={history}> + <AgentPolicyContextProvider> + <PackageInstallProvider notifications={startServices.notifications}> + <IntegrationsHeader {...{ setHeaderActionMenu }} /> + {children} + </PackageInstallProvider> + </AgentPolicyContextProvider> + </Router> + </startServices.customIntegrations.ContextProvider> + </FleetStatusProvider> + </UIExtensionsContext.Provider> + </EuiThemeProvider> + </KibanaVersionContext.Provider> + </ConfigContext.Provider> + </EuiErrorBoundary> + </KibanaContextProvider> + </startServices.i18n.Context> + </RedirectAppLinks> + ); + } +); export const AppRoutes = memo(() => { const { modal, setModal } = useUrlModal(); diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.component.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.component.tsx new file mode 100644 index 0000000000000..1fa673890fa82 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.component.tsx @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 styled from 'styled-components'; + +import { + EuiPopover, + EuiText, + EuiForm, + EuiFormRow, + EuiFieldText, + EuiCopy, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiLink, + EuiHeaderLink, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export interface Props { + endpointUrl: string; + cloudId: string; + managementUrl?: string; + learnMoreUrl: string; +} + +const Description = styled(EuiText)` + margin-bottom: ${({ theme }) => theme.eui.euiSizeL}; +`; + +export const DeploymentDetails = ({ endpointUrl, cloudId, learnMoreUrl, managementUrl }: Props) => { + const [isOpen, setIsOpen] = React.useState(false); + + const button = ( + <EuiHeaderLink onClick={() => setIsOpen(!isOpen)} iconType="iInCircle" iconSide="left" isActive> + {i18n.translate('xpack.fleet.integrations.deploymentButton', { + defaultMessage: 'View deployment details', + })} + </EuiHeaderLink> + ); + + const management = managementUrl ? ( + <EuiFormRow label="API keys" fullWidth> + <EuiFlexGroup gutterSize="m" alignItems="center"> + <EuiFlexItem> + <EuiButton href={managementUrl}>Create and manage API keys</EuiButton> + </EuiFlexItem> + <EuiFlexItem> + <EuiLink external href={learnMoreUrl} target="_blank"> + Learn more + </EuiLink> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFormRow> + ) : null; + + return ( + <EuiPopover + isOpen={isOpen} + closePopover={() => setIsOpen(false)} + button={button} + anchorPosition="downCenter" + > + <div style={{ width: 450 }}> + <Description> + Send data to Elastic from your applications by referencing your deployment and + Elasticsearch information. + </Description> + <EuiForm component="div"> + <EuiFormRow label="Elasticsearch endpoint" fullWidth isDisabled> + <EuiFlexGroup gutterSize="s"> + <EuiFlexItem> + <EuiFieldText value={endpointUrl} fullWidth disabled /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiCopy textToCopy={endpointUrl}> + {(copy) => ( + <EuiButtonIcon + onClick={copy} + iconType="copyClipboard" + display="base" + size="m" + /> + )} + </EuiCopy> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFormRow> + <EuiFormRow label="Cloud ID" fullWidth> + <EuiFlexGroup gutterSize="s"> + <EuiFlexItem> + <EuiFieldText value={cloudId} fullWidth disabled /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiCopy textToCopy={cloudId}> + {(copy) => ( + <EuiButtonIcon + onClick={copy} + iconType="copyClipboard" + display="base" + size="m" + /> + )} + </EuiCopy> + </EuiFlexItem> + </EuiFlexGroup> + </EuiFormRow> + {management} + </EuiForm> + </div> + </EuiPopover> + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.stories.tsx new file mode 100644 index 0000000000000..445bf471c0fe9 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.stories.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { Meta } from '@storybook/react'; +import { EuiHeader } from '@elastic/eui'; + +import { DeploymentDetails as ConnectedComponent } from './deployment_details'; +import type { Props as PureComponentProps } from './deployment_details.component'; +import { DeploymentDetails as PureComponent } from './deployment_details.component'; + +export default { + title: 'Sections/EPM/Deployment Details', + description: '', + decorators: [ + (storyFn) => { + const sections = [{ items: [] }, { items: [storyFn()] }]; + return <EuiHeader sections={sections} />; + }, + ], +} as Meta; + +export const DeploymentDetails = () => { + return <ConnectedComponent />; +}; + +DeploymentDetails.args = { + isCloudEnabled: true, +}; + +DeploymentDetails.argTypes = { + isCloudEnabled: { + type: { + name: 'boolean', + }, + defaultValue: true, + control: { + type: 'boolean', + }, + }, +}; + +export const Component = (props: PureComponentProps) => { + return <PureComponent {...props} />; +}; + +Component.args = { + cloudId: 'cloud-id', + endpointUrl: 'https://endpoint-url', + learnMoreUrl: 'https://learn-more-url', + managementUrl: 'https://management-url', +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx new file mode 100644 index 0000000000000..48c8fa56fb91b --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.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 { useStartServices } from '../../hooks'; + +import { DeploymentDetails as Component } from './deployment_details.component'; + +export const DeploymentDetails = () => { + const { share, cloud, docLinks } = useStartServices(); + + // If the cloud plugin isn't enabled, we can't display the flyout. + if (!cloud) { + return null; + } + + const { isCloudEnabled, cloudId, cname } = cloud; + + // If cloud isn't enabled, we don't have a cloudId or a cname, we can't display the flyout. + if (!isCloudEnabled || !cloudId || !cname) { + return null; + } + + // If the cname doesn't start with a known prefix, we can't display the flyout. + // TODO: dover - this is a short term solution, see https://github.com/elastic/kibana/pull/114287#issuecomment-940111026 + if ( + !( + cname.endsWith('elastic-cloud.com') || + cname.endsWith('found.io') || + cname.endsWith('found.no') + ) + ) { + return null; + } + + const cnameNormalized = cname.startsWith('.') ? cname.substring(1) : cname; + const endpointUrl = `https://${cloudId}.${cnameNormalized}`; + + const managementUrl = share.url.locators + .get('MANAGEMENT_APP_LOCATOR') + ?.useUrl({ sectionId: 'security', appId: 'api_keys' }); + + const learnMoreUrl = docLinks.links.fleet.apiKeysLearnMore; + + return <Component {...{ cloudId, endpointUrl, managementUrl, learnMoreUrl }} />; +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/header.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/header.tsx new file mode 100644 index 0000000000000..e87c63e98ef28 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/header.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiHeaderSectionItem, EuiHeaderSection, EuiHeaderLinks } from '@elastic/eui'; + +import type { AppMountParameters } from 'kibana/public'; + +import { HeaderPortal } from './header_portal'; +import { DeploymentDetails } from './deployment_details'; + +export const IntegrationsHeader = ({ + setHeaderActionMenu, +}: { + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; +}) => { + return ( + <HeaderPortal {...{ setHeaderActionMenu }}> + <EuiHeaderSection grow={false}> + <EuiHeaderSectionItem> + <EuiHeaderLinks> + <DeploymentDetails /> + </EuiHeaderLinks> + </EuiHeaderSectionItem> + </EuiHeaderSection> + </HeaderPortal> + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx new file mode 100644 index 0000000000000..d3dbbcf9628ec --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { AppMountParameters } from 'kibana/public'; +import type { FC } from 'react'; +import React, { useEffect, useMemo } from 'react'; +import { createPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; + +import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; + +export interface Props { + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; +} + +export const HeaderPortal: FC<Props> = ({ children, setHeaderActionMenu }) => { + const portalNode = useMemo(() => createPortalNode(), []); + + useEffect(() => { + setHeaderActionMenu((element) => { + const mount = toMountPoint(<OutPortal node={portalNode} />); + return mount(element); + }); + + return () => { + portalNode.unmount(); + setHeaderActionMenu(undefined); + }; + }, [portalNode, setHeaderActionMenu]); + + return <InPortal node={portalNode}>{children}</InPortal>; +}; diff --git a/x-pack/test/api_integration/apis/xpack_legacy/index.js b/x-pack/plugins/fleet/public/applications/integrations/components/header/index.ts similarity index 64% rename from x-pack/test/api_integration/apis/xpack_legacy/index.js rename to x-pack/plugins/fleet/public/applications/integrations/components/header/index.ts index 4d3046286fb9d..e0a342326d972 100644 --- a/x-pack/test/api_integration/apis/xpack_legacy/index.js +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/index.ts @@ -5,8 +5,4 @@ * 2.0. */ -export default function ({ loadTestFile }) { - describe('xpack_legacy', () => { - loadTestFile(require.resolve('./settings')); - }); -} +export { IntegrationsHeader } from './header'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_local_search.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_local_search.tsx index a8ed849f50a8a..458c4d94f9cd4 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_local_search.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_local_search.tsx @@ -14,7 +14,7 @@ export const searchIdField = 'id'; export const fieldsToSearch = ['name', 'title', 'description']; export function useLocalSearch(packageList: IntegrationCardItem[]) { - const localSearchRef = useRef<LocalSearch | null>(null); + const localSearchRef = useRef<LocalSearch>(new LocalSearch(searchIdField)); useEffect(() => { const localSearch = new LocalSearch(searchIdField); diff --git a/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.test.ts b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_merge_epr_with_replacements.test.ts similarity index 82% rename from x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.test.ts rename to x-pack/plugins/fleet/public/applications/integrations/hooks/use_merge_epr_with_replacements.test.ts index 687fb01b04546..d5d8aa093e300 100644 --- a/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.test.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_merge_epr_with_replacements.test.ts @@ -5,10 +5,10 @@ * 2.0. */ -import type { PackageListItem } from '../../common/types/models'; -import type { CustomIntegration } from '../../../../../src/plugins/custom_integrations/common'; +import type { PackageListItem } from '../../../../common/types/models'; +import type { CustomIntegration } from '../../../../../../../src/plugins/custom_integrations/common'; -import type { IntegrationCategory } from '../../../../../src/plugins/custom_integrations/common'; +import type { IntegrationCategory } from '../../../../../../../src/plugins/custom_integrations/common'; import { useMergeEprPackagesWithReplacements } from './use_merge_epr_with_replacements'; @@ -46,7 +46,7 @@ describe('useMergeEprWithReplacements', () => { }, ]); - expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements)).toEqual([ { name: 'aws', release: 'ga', @@ -80,7 +80,7 @@ describe('useMergeEprWithReplacements', () => { }, ]); - expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements)).toEqual([ { eprOverlap: 'activemq', id: 'activemq-logs', @@ -108,7 +108,7 @@ describe('useMergeEprWithReplacements', () => { }, ]); - expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements)).toEqual([ { name: 'activemq', release: 'beta', @@ -120,32 +120,6 @@ describe('useMergeEprWithReplacements', () => { ]); }); - test('should respect category assignment', () => { - const eprPackages: PackageListItem[] = mockEprPackages([ - { - name: 'activemq', - release: 'beta', - }, - ]); - const replacements: CustomIntegration[] = mockIntegrations([ - { - id: 'prometheus', - categories: ['monitoring', 'datastore'], - }, - { - id: 'oracle', - categories: ['datastore'], - }, - ]); - - expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, 'web')).toEqual([ - { - name: 'activemq', - release: 'beta', - }, - ]); - }); - test('should consists of all 3 types (ga eprs, replacements for non-ga eprs, replacements without epr equivalent', () => { const eprPackages: PackageListItem[] = mockEprPackages([ { @@ -190,7 +164,7 @@ describe('useMergeEprWithReplacements', () => { }, ]); - expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements)).toEqual([ { name: 'aws', release: 'ga', diff --git a/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.ts b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_merge_epr_with_replacements.ts similarity index 75% rename from x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.ts rename to x-pack/plugins/fleet/public/applications/integrations/hooks/use_merge_epr_with_replacements.ts index ac53badc2446d..4c59f0ef45123 100644 --- a/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_merge_epr_with_replacements.ts @@ -5,12 +5,9 @@ * 2.0. */ -import type { PackageListItem } from '../../common/types/models'; -import type { - CustomIntegration, - IntegrationCategory, -} from '../../../../../src/plugins/custom_integrations/common'; -import { filterCustomIntegrations } from '../../../../../src/plugins/custom_integrations/public'; +import type { PackageListItem } from '../../../../common/types/models'; +import type { CustomIntegration } from '../../../../../../../src/plugins/custom_integrations/common'; +import { filterCustomIntegrations } from '../../../../../../../src/plugins/custom_integrations/public'; // Export this as a utility to find replacements for a package (e.g. in the overview-page for an EPR package) function findReplacementsForEprPackage( @@ -26,17 +23,13 @@ function findReplacementsForEprPackage( export function useMergeEprPackagesWithReplacements( eprPackages: PackageListItem[], - replacements: CustomIntegration[], - category: IntegrationCategory | '' + replacements: CustomIntegration[] ): Array<PackageListItem | CustomIntegration> { const merged: Array<PackageListItem | CustomIntegration> = []; - - const filteredReplacements = replacements.filter((customIntegration) => { - return !category || customIntegration.categories.includes(category); - }); + const filteredReplacements = replacements; // Either select replacement or select beat - eprPackages.forEach((eprPackage) => { + eprPackages.forEach((eprPackage: PackageListItem) => { const hits = findReplacementsForEprPackage( filteredReplacements, eprPackage.name, diff --git a/x-pack/plugins/fleet/public/applications/integrations/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/index.tsx index da8959a019ce5..0abb78f850076 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/index.tsx @@ -37,6 +37,7 @@ interface IntegrationsAppProps { history: AppMountParameters['history']; kibanaVersion: string; extensions: UIExtensionsStorage; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; } const IntegrationsApp = ({ basepath, @@ -45,6 +46,7 @@ const IntegrationsApp = ({ history, kibanaVersion, extensions, + setHeaderActionMenu, }: IntegrationsAppProps) => { return ( <IntegrationsAppContext @@ -54,6 +56,7 @@ const IntegrationsApp = ({ history={history} kibanaVersion={kibanaVersion} extensions={extensions} + setHeaderActionMenu={setHeaderActionMenu} > <WithPermissionsAndSetup> <AppRoutes /> @@ -64,7 +67,7 @@ const IntegrationsApp = ({ export function renderApp( startServices: FleetStartServices, - { element, appBasePath, history }: AppMountParameters, + { element, appBasePath, history, setHeaderActionMenu }: AppMountParameters, config: FleetConfigType, kibanaVersion: string, extensions: UIExtensionsStorage @@ -77,6 +80,7 @@ export function renderApp( history={history} kibanaVersion={kibanaVersion} extensions={extensions} + setHeaderActionMenu={setHeaderActionMenu} />, element ); diff --git a/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx b/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx index 70e55c9bd56b0..0c46e1af301cf 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx @@ -5,20 +5,12 @@ * 2.0. */ import React, { memo } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiSpacer, EuiText } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; - -import styled, { useTheme } from 'styled-components'; - -import type { EuiTheme } from 'src/plugins/kibana_react/common'; - import { useLink } from '../../../hooks'; import type { Section } from '../sections'; -import { useLinks } from '../hooks'; - import { WithHeaderLayout } from './'; interface Props { @@ -26,45 +18,18 @@ interface Props { children?: React.ReactNode; } -const Illustration = styled(EuiImage)` - margin-bottom: -68px; - position: relative; - top: -20px; - width: 80%; -`; - -const HeroImage = memo(() => { - const { toSharedAssets } = useLinks(); - const theme = useTheme() as EuiTheme; - const IS_DARK_THEME = theme.darkMode; - - return ( - <Illustration - alt={i18n.translate('xpack.fleet.epm.illustrationAltText', { - defaultMessage: 'Illustration of an integration', - })} - url={ - IS_DARK_THEME - ? toSharedAssets('illustration_integrations_darkmode.svg') - : toSharedAssets('illustration_integrations_lightmode.svg') - } - /> - ); -}); - export const DefaultLayout: React.FunctionComponent<Props> = memo(({ section, children }) => { const { getHref } = useLink(); return ( <WithHeaderLayout - rightColumn={<HeroImage />} leftColumn={ <EuiFlexGroup direction="column" gutterSize="none" justifyContent="center"> <EuiText> <h1> <FormattedMessage id="xpack.fleet.integrationsHeaderTitle" - defaultMessage="Elastic Agent Integrations" + defaultMessage="Integrations" /> </h1> </EuiText> @@ -72,11 +37,11 @@ export const DefaultLayout: React.FunctionComponent<Props> = memo(({ section, ch <EuiSpacer size="s" /> <EuiFlexItem grow={false}> - <EuiText size="m" color="subdued"> + <EuiText size="s" color="subdued"> <p> <FormattedMessage id="xpack.fleet.epm.pageSubtitle" - defaultMessage="Collect data from popular apps and services using Elastic Agent" + defaultMessage="Choose an integration to start collecting and analyzing your data" /> </p> </EuiText> diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.stories.tsx new file mode 100644 index 0000000000000..86b34f2415e2e --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.stories.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { Meta } from '@storybook/react'; + +import { action } from '@storybook/addon-actions'; + +import { IntegrationPreference as Component } from './integration_preference'; + +export default { + title: 'Sections/EPM/Integration Preference', + description: '', + decorators: [ + (storyFn, { globals }) => ( + <div + style={{ + padding: 40, + backgroundColor: + globals.euiTheme === 'v8.dark' || globals.euiTheme === 'v7.dark' ? '#1D1E24' : '#FFF', + width: 280, + }} + > + {storyFn()} + </div> + ), + ], +} as Meta; + +export const IntegrationPreference = () => { + return <Component initialType="recommended" onChange={action('onChange')} />; +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx new file mode 100644 index 0000000000000..ecc5c22c8d8ce --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 styled from 'styled-components'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiPanel, + EuiLink, + EuiText, + EuiForm, + EuiRadioGroup, + EuiSpacer, + EuiIconTip, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; + +export type IntegrationPreferenceType = 'recommended' | 'beats' | 'agent'; + +interface Option { + type: IntegrationPreferenceType; + label: React.ReactNode; +} + +export interface Props { + initialType: IntegrationPreferenceType; + onChange: (type: IntegrationPreferenceType) => void; +} + +const link = ( + <EuiLink href="#"> + <FormattedMessage + id="xpack.fleet.epm.integrationPreference.titleLink" + defaultMessage="Elastic Agent and Beats" + /> + </EuiLink> +); + +const title = ( + <FormattedMessage + id="xpack.fleet.epm.integrationPreference.title" + defaultMessage="When an integration is available for {link}, show:" + values={{ link }} + /> +); + +const recommendedTooltip = ( + <FormattedMessage + id="xpack.fleet.epm.integrationPreference.recommendedTooltip" + defaultMessage="Generally available (GA) integrations are recommended over beta and experimental." + /> +); + +const Item = styled(EuiFlexItem)` + padding-left: ${(props) => props.theme.eui.euiSizeXS}; +`; + +const options: Option[] = [ + { + type: 'recommended', + label: ( + <EuiFlexGroup alignItems="center" gutterSize="none"> + <EuiFlexItem grow={false}> + {i18n.translate('xpack.fleet.epm.integrationPreference.recommendedLabel', { + defaultMessage: 'Recommended', + })} + </EuiFlexItem> + <Item> + <EuiIconTip content={recommendedTooltip} /> + </Item> + </EuiFlexGroup> + ), + }, + { + type: 'agent', + label: i18n.translate('xpack.fleet.epm.integrationPreference.elasticAgentLabel', { + defaultMessage: 'Elastic Agent only', + }), + }, + { + type: 'beats', + label: i18n.translate('xpack.fleet.epm.integrationPreference.beatsLabel', { + defaultMessage: 'Beats only', + }), + }, +]; + +export const IntegrationPreference = ({ initialType, onChange }: Props) => { + const [idSelected, setIdSelected] = React.useState<IntegrationPreferenceType>(initialType); + const radios = options.map((option) => ({ + id: option.type, + value: option.type, + label: option.label, + })); + + return ( + <EuiPanel hasShadow={false} paddingSize="none"> + <EuiText size="s">{title}</EuiText> + <EuiSpacer size="m" /> + <EuiForm> + <EuiRadioGroup + options={radios} + idSelected={idSelected} + onChange={(id, value) => { + setIdSelected(id as IntegrationPreferenceType); + onChange(value as IntegrationPreferenceType); + }} + name="preference" + /> + </EuiForm> + </EuiPanel> + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx index bddbc4f027b4f..86bac94bc50cd 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx @@ -22,7 +22,7 @@ export default { type Args = Omit<PackageCardProps, 'status'> & { width: number }; const args: Args = { - width: 250, + width: 280, title: 'Title', description: 'Description', name: 'beats', @@ -32,6 +32,7 @@ const args: Args = { url: '/', icons: [], integration: '', + categories: ['foobar'], }; const argTypes = { diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx index a68499dbd8dd0..091eb4c97183d 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx @@ -7,7 +7,7 @@ import React from 'react'; import styled from 'styled-components'; -import { EuiCard } from '@elastic/eui'; +import { EuiCard, EuiFlexItem, EuiBadge, EuiToolTip, EuiSpacer } from '@elastic/eui'; import { CardIcon } from '../../../../../components/package_icon'; import type { IntegrationCardItem } from '../../../../../../common/types/models/epm'; @@ -16,10 +16,10 @@ import { RELEASE_BADGE_DESCRIPTION, RELEASE_BADGE_LABEL } from './release_badge' export type PackageCardProps = IntegrationCardItem; -// adding the `href` causes EuiCard to use a `a` instead of a `button` -// `a` tags use `euiLinkColor` which results in blueish Badge text +// Min-height is roughly 3 lines of content. +// This keeps the cards from looking overly unbalanced because of content differences. const Card = styled(EuiCard)` - color: inherit; + min-height: 127px; `; export function PackageCard({ @@ -32,14 +32,28 @@ export function PackageCard({ url, release, }: PackageCardProps) { - const betaBadgeLabel = release && release !== 'ga' ? RELEASE_BADGE_LABEL[release] : undefined; - const betaBadgeLabelTooltipContent = - release && release !== 'ga' ? RELEASE_BADGE_DESCRIPTION[release] : undefined; + let releaseBadge: React.ReactNode | null = null; + + if (release && release !== 'ga') { + releaseBadge = ( + <EuiFlexItem grow={false}> + <EuiSpacer size="xs" /> + <span> + <EuiToolTip display="inlineBlock" content={RELEASE_BADGE_DESCRIPTION[release]}> + <EuiBadge color="hollow">{RELEASE_BADGE_LABEL[release]}</EuiBadge> + </EuiToolTip> + </span> + </EuiFlexItem> + ); + } return ( <Card + layout="horizontal" title={title || ''} + titleSize="xs" description={description} + hasBorder icon={ <CardIcon icons={icons} @@ -50,9 +64,9 @@ export function PackageCard({ /> } href={url} - betaBadgeLabel={betaBadgeLabel} - betaBadgeTooltipContent={betaBadgeLabelTooltipContent} target={url.startsWith('http') || url.startsWith('https') ? '_blank' : undefined} - /> + > + {releaseBadge} + </Card> ); } diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.stories.tsx index e4bd1da842867..f43c18d167717 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.stories.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.stories.tsx @@ -47,6 +47,7 @@ export const List = (props: Args) => ( url: 'https://example.com', icons: [], integration: 'integation', + categories: ['web'], }, { title: 'Package Two', @@ -58,6 +59,7 @@ export const List = (props: Args) => ( url: 'https://example.com', icons: [], integration: 'integation', + categories: ['web'], }, { title: 'Package Three', @@ -69,6 +71,7 @@ export const List = (props: Args) => ( url: 'https://example.com', icons: [], integration: 'integation', + categories: ['web'], }, { title: 'Package Four', @@ -80,6 +83,7 @@ export const List = (props: Args) => ( url: 'https://example.com', icons: [], integration: 'integation', + categories: ['web'], }, { title: 'Package Five', @@ -91,6 +95,7 @@ export const List = (props: Args) => ( url: 'https://example.com', icons: [], integration: 'integation', + categories: ['web'], }, { title: 'Package Six', @@ -102,6 +107,7 @@ export const List = (props: Args) => ( url: 'https://example.com', icons: [], integration: 'integation', + categories: ['web'], }, ]} onSearchChange={action('onSearchChange')} diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx index 1cffd5292b6a2..00adb2a7b4ffb 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import type { ReactNode } from 'react'; -import React, { Fragment, useCallback, useState } from 'react'; +import type { ReactNode, FunctionComponent } from 'react'; +import React, { useCallback, useState, useRef, useEffect } from 'react'; import { EuiFlexGrid, EuiFlexGroup, @@ -20,7 +20,6 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { useStartServices } from '../../../../../hooks'; import { Loading } from '../../../components'; import { useLocalSearch, searchIdField } from '../../../hooks'; @@ -30,8 +29,8 @@ import { PackageCard } from './package_card'; export interface Props { isLoading?: boolean; - controls?: ReactNode; - title: string; + controls?: ReactNode | ReactNode[]; + title?: string; list: IntegrationCardItem[]; initialSearch?: string; setSelectedCategory: (category: string) => void; @@ -40,7 +39,7 @@ export interface Props { callout?: JSX.Element | null; } -export function PackageListGrid({ +export const PackageListGrid: FunctionComponent<Props> = ({ isLoading, controls, title, @@ -50,9 +49,23 @@ export function PackageListGrid({ setSelectedCategory, showMissingIntegrationMessage = false, callout, -}: Props) { +}) => { const [searchTerm, setSearchTerm] = useState(initialSearch || ''); const localSearchRef = useLocalSearch(list); + const menuRef = useRef<HTMLDivElement>(null); + const [isSticky, setIsSticky] = useState(false); + const [windowScrollY] = useState(window.scrollY); + + useEffect(() => { + const menuRefCurrent = menuRef.current; + const onScroll = () => { + if (menuRefCurrent) { + setIsSticky(menuRefCurrent?.getBoundingClientRect().top < 110); + } + }; + window.addEventListener('scroll', onScroll); + return () => window.removeEventListener('scroll', onScroll); + }, [windowScrollY, isSticky]); const onQueryChange = ({ queryText: userInput, @@ -71,7 +84,7 @@ export function PackageListGrid({ setSearchTerm(''); }; - const controlsContent = <ControlsColumn title={title} controls={controls} />; + const controlsContent = <ControlsColumn title={title} controls={controls} sticky={isSticky} />; let gridContent: JSX.Element; if (isLoading || !localSearchRef.current) { @@ -93,58 +106,68 @@ export function PackageListGrid({ } return ( - <EuiFlexGroup alignItems="flexStart"> - <EuiFlexItem grow={1}>{controlsContent}</EuiFlexItem> - <EuiFlexItem grow={3}> - <EuiSearchBar - query={searchTerm || undefined} - box={{ - placeholder: i18n.translate('xpack.fleet.epmList.searchPackagesPlaceholder', { - defaultMessage: 'Search for integrations', - }), - incremental: true, - }} - onChange={onQueryChange} - /> - {callout ? ( - <> - <EuiSpacer /> - {callout} - </> - ) : null} - <EuiSpacer /> - {gridContent} - {showMissingIntegrationMessage && ( - <> - <EuiSpacer size="xxl" /> - <MissingIntegrationContent - resetQuery={resetQuery} - setSelectedCategory={setSelectedCategory} - /> - </> - )} - </EuiFlexItem> - </EuiFlexGroup> + <div ref={menuRef}> + <EuiFlexGroup alignItems="flexStart" gutterSize="xl"> + <EuiFlexItem grow={1} className={isSticky ? 'kbnStickyMenu' : ''}> + {controlsContent} + </EuiFlexItem> + <EuiFlexItem grow={5}> + <EuiSearchBar + query={searchTerm || undefined} + box={{ + placeholder: i18n.translate('xpack.fleet.epmList.searchPackagesPlaceholder', { + defaultMessage: 'Search for integrations', + }), + incremental: true, + }} + onChange={onQueryChange} + /> + {callout ? ( + <> + <EuiSpacer /> + {callout} + </> + ) : null} + <EuiSpacer /> + {gridContent} + {showMissingIntegrationMessage && ( + <> + <EuiSpacer /> + <MissingIntegrationContent + resetQuery={resetQuery} + setSelectedCategory={setSelectedCategory} + /> + </> + )} + </EuiFlexItem> + </EuiFlexGroup> + </div> ); -} +}; interface ControlsColumnProps { controls: ReactNode; - title: string; + title: string | undefined; + sticky: boolean; } -function ControlsColumn({ controls, title }: ControlsColumnProps) { +function ControlsColumn({ controls, title, sticky }: ControlsColumnProps) { + let titleContent; + if (title) { + titleContent = ( + <> + <EuiTitle size="s"> + <h2>{title}</h2> + </EuiTitle> + <EuiSpacer size="l" /> + </> + ); + } return ( - <Fragment> - <EuiTitle size="s"> - <h2>{title}</h2> - </EuiTitle> - <EuiSpacer size="l" /> - <EuiFlexGroup> - <EuiFlexItem grow={4}>{controls}</EuiFlexItem> - <EuiFlexItem grow={1} /> - </EuiFlexGroup> - </Fragment> + <EuiFlexGroup direction="column" className={sticky ? 'kbnStickyMenu' : ''} gutterSize="none"> + {titleContent} + {controls} + </EuiFlexGroup> ); } @@ -196,20 +219,17 @@ function MissingIntegrationContent({ resetQuery, setSelectedCategory, }: MissingIntegrationContentProps) { - const { - application: { getUrlForApp }, - } = useStartServices(); const handleCustomInputsLinkClick = useCallback(() => { resetQuery(); setSelectedCategory('custom'); }, [resetQuery, setSelectedCategory]); return ( - <EuiText> + <EuiText size="s" color="subdued"> <p> <FormattedMessage id="xpack.fleet.integrations.missing" - defaultMessage="Don't see an integration? Collect any logs or metrics using our {customInputsLink}, or add data using {beatsTutorialLink}. Request new integrations using our {discussForumLink}." + defaultMessage="Don't see an integration? Collect any logs or metrics using our {customInputsLink}. Request new integrations using our {discussForumLink}." values={{ customInputsLink: ( <EuiLink onClick={handleCustomInputsLinkClick}> @@ -227,14 +247,6 @@ function MissingIntegrationContent({ /> </EuiLink> ), - beatsTutorialLink: ( - <EuiLink href={getUrlForApp('home', { path: '#/tutorial_directory' })}> - <FormattedMessage - id="xpack.fleet.integrations.beatsModulesLink" - defaultMessage="Beats modules" - /> - </EuiLink> - ), }} /> </p> diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx index 6d075faeef308..a8d27580e0bd1 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx @@ -9,6 +9,7 @@ import React, { useEffect, useState } from 'react'; import { Redirect } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer } from '@elastic/eui'; +import { groupBy } from 'lodash'; import { Loading, Error, ExtensionWrapper } from '../../../../../components'; @@ -67,8 +68,26 @@ export const AssetsPage = ({ packageInfo }: AssetsPanelProps) => { id, type, })); - const { savedObjects } = await savedObjectsClient.bulkGet(objectsToGet); - setAssetsSavedObjects(savedObjects as AssetSavedObject[]); + + // We don't have an API to know which SO types a user has access to, so instead we make a request for each + // SO type and ignore the 403 errors + const objectsByType = await Promise.all( + Object.entries(groupBy(objectsToGet, 'type')).map(([type, objects]) => + savedObjectsClient + .bulkGet(objects) + // Ignore privilege errors + .catch((e: any) => { + if (e?.body?.statusCode === 403) { + return { savedObjects: [] }; + } else { + throw e; + } + }) + .then(({ savedObjects }) => savedObjects as AssetSavedObject[]) + ) + ); + + setAssetsSavedObjects(objectsByType.flat()); } catch (e) { setFetchError(e); } finally { diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx index d70b6c68016be..d442f8a13e27e 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx @@ -11,6 +11,7 @@ import { act, cleanup } from '@testing-library/react'; import { INTEGRATIONS_ROUTING_PATHS, pagePathGetters } from '../../../../constants'; import type { + CheckPermissionsResponse, GetAgentPoliciesResponse, GetFleetStatusResponse, GetInfoResponse, @@ -23,6 +24,7 @@ import type { } from '../../../../../../../common/types/models'; import { agentPolicyRouteService, + appRoutesService, epmRouteService, fleetSetupRouteService, packagePolicyRouteService, @@ -260,6 +262,7 @@ interface EpmPackageDetailsResponseProvidersMock { fleetSetup: jest.MockedFunction<() => GetFleetStatusResponse>; packagePolicyList: jest.MockedFunction<() => GetPackagePoliciesResponse>; agentPolicyList: jest.MockedFunction<() => GetAgentPoliciesResponse>; + appCheckPermissions: jest.MockedFunction<() => CheckPermissionsResponse>; } const mockApiCalls = ( @@ -740,6 +743,10 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos }, }; + const appCheckPermissionsResponse: CheckPermissionsResponse = { + success: true, + }; + const mockedApiInterface: MockedApi<EpmPackageDetailsResponseProvidersMock> = { waitForApi() { return new Promise((resolve) => { @@ -757,6 +764,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos fleetSetup: jest.fn().mockReturnValue(agentsSetupResponse), packagePolicyList: jest.fn().mockReturnValue(packagePoliciesResponse), agentPolicyList: jest.fn().mockReturnValue(agentPoliciesResponse), + appCheckPermissions: jest.fn().mockReturnValue(appCheckPermissionsResponse), }, }; @@ -792,6 +800,11 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos return mockedApiInterface.responseProvider.epmGetStats(); } + if (path === appRoutesService.getCheckPermissionsPath()) { + markApiCallAsHandled(); + return mockedApiInterface.responseProvider.appCheckPermissions(); + } + const err = new Error(`API [GET ${path}] is not MOCKED!`); // eslint-disable-next-line no-console console.error(err); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index 82436eb4d3f51..ade290aab4e5e 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -8,10 +8,12 @@ import type { ReactEventHandler } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Redirect, Route, Switch, useLocation, useParams, useHistory } from 'react-router-dom'; import styled from 'styled-components'; +import type { EuiToolTipProps } from '@elastic/eui'; import { EuiBetaBadge, EuiButton, EuiButtonEmpty, + EuiCallOut, EuiDescriptionList, EuiDescriptionListDescription, EuiDescriptionListTitle, @@ -19,6 +21,7 @@ import { EuiFlexItem, EuiSpacer, EuiText, + EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -30,6 +33,7 @@ import { useUIExtension, useBreadcrumbs, useStartServices, + usePermissionCheck, } from '../../../../hooks'; import { PLUGIN_ID, @@ -61,6 +65,7 @@ import { OverviewPage } from './overview'; import { PackagePoliciesPage } from './policies'; import { SettingsPage } from './settings'; import { CustomViewPage } from './custom'; + import './index.scss'; export interface DetailParams { @@ -95,7 +100,11 @@ export function Detail() { const { getId: getAgentPolicyId } = useAgentPolicyContext(); const { pkgkey, panel } = useParams<DetailParams>(); const { getHref } = useLink(); - const hasWriteCapabilites = useCapabilities().write; + const hasWriteCapabilities = useCapabilities().write; + const permissionCheck = usePermissionCheck(); + const missingSecurityConfiguration = + !permissionCheck.data?.success && permissionCheck.data?.error === 'MISSING_SECURITY'; + const userCanInstallIntegrations = hasWriteCapabilities && permissionCheck.data?.success; const history = useHistory(); const { pathname, search, hash } = useLocation(); const queryParams = useMemo(() => new URLSearchParams(search), [search]); @@ -127,9 +136,11 @@ export function Detail() { const { data: packageInfoData, error: packageInfoError, - isLoading, + isLoading: packageInfoLoading, } = useGetPackageInfoByKey(pkgkey); + const isLoading = packageInfoLoading || permissionCheck.isLoading; + const showCustomTab = useUIExtension(packageInfoData?.response.name ?? '', 'package-detail-custom') !== undefined; @@ -327,10 +338,9 @@ export function Detail() { { isDivider: true }, { content: ( - // eslint-disable-next-line @elastic/eui/href-or-on-click - <EuiButton + <EuiButtonWithTooltip fill - isDisabled={!hasWriteCapabilites} + isDisabled={!userCanInstallIntegrations} iconType="plusInCircle" href={getHref('add_integration_to_policy', { pkgkey, @@ -341,6 +351,23 @@ export function Detail() { })} onClick={handleAddIntegrationPolicyClick} data-test-subj="addIntegrationPolicyButton" + tooltip={ + !userCanInstallIntegrations + ? { + content: missingSecurityConfiguration ? ( + <FormattedMessage + id="xpack.fleet.epm.addPackagePolicyButtonSecurityRequiredTooltip" + defaultMessage="To add Elastic Agent Integrations, you must have security enabled and have the minimum required privileges. Contact your administrator." + /> + ) : ( + <FormattedMessage + id="xpack.fleet.epm.addPackagePolicyButtonPrivilegesRequiredTooltip" + defaultMessage="To add Elastic Agent integrations, you must have the minimum required privileges. Contact your adminstrator." + /> + ), + } + : undefined + } > <FormattedMessage id="xpack.fleet.epm.addPackagePolicyButtonText" @@ -349,7 +376,7 @@ export function Detail() { packageName: integrationInfo?.title || packageInfo.title, }} /> - </EuiButton> + </EuiButtonWithTooltip> ), }, ].map((item, index) => ( @@ -370,16 +397,17 @@ export function Detail() { </> ) : undefined, [ - getHref, - handleAddIntegrationPolicyClick, - hasWriteCapabilites, - integration, - integrationInfo, packageInfo, + updateAvailable, packageInstallStatus, + userCanInstallIntegrations, + getHref, pkgkey, - updateAvailable, + integration, agentPolicyIdFromContext, + handleAddIntegrationPolicyClick, + missingSecurityConfiguration, + integrationInfo?.title, ] ); @@ -407,7 +435,7 @@ export function Detail() { }, ]; - if (packageInstallStatus === InstallStatus.installed) { + if (userCanInstallIntegrations && packageInstallStatus === InstallStatus.installed) { tabs.push({ id: 'policies', name: ( @@ -443,21 +471,23 @@ export function Detail() { }); } - tabs.push({ - id: 'settings', - name: ( - <FormattedMessage - id="xpack.fleet.epm.packageDetailsNav.settingsLinkText" - defaultMessage="Settings" - /> - ), - isSelected: panel === 'settings', - 'data-test-subj': `tab-settings`, - href: getHref('integration_details_settings', { - pkgkey: packageInfoKey, - ...(integration ? { integration } : {}), - }), - }); + if (userCanInstallIntegrations) { + tabs.push({ + id: 'settings', + name: ( + <FormattedMessage + id="xpack.fleet.epm.packageDetailsNav.settingsLinkText" + defaultMessage="Settings" + /> + ), + isSelected: panel === 'settings', + 'data-test-subj': `tab-settings`, + href: getHref('integration_details_settings', { + pkgkey: packageInfoKey, + ...(integration ? { integration } : {}), + }), + }); + } if (showCustomTab) { tabs.push({ @@ -478,13 +508,55 @@ export function Detail() { } return tabs; - }, [packageInfo, panel, getHref, integration, packageInstallStatus, showCustomTab, CustomAssets]); + }, [ + packageInfo, + panel, + getHref, + integration, + userCanInstallIntegrations, + packageInstallStatus, + CustomAssets, + showCustomTab, + ]); + + const securityCallout = missingSecurityConfiguration ? ( + <> + <EuiCallOut + color="warning" + iconType="lock" + title={ + <FormattedMessage + id="xpack.fleet.epm.packageDetailsSecurityRequiredCalloutTitle" + defaultMessage="Security needs to be enabled in order to add Elastic Agent integrations" + /> + } + > + <FormattedMessage + id="xpack.fleet.epm.packageDetailsSecurityRequiredCalloutDescription" + defaultMessage="In order to fully use Fleet, you must enable Elasticsearch and Kibana security features. + Follow the {guideLink} to enable security." + values={{ + guideLink: ( + <a href={services.http.basePath.prepend('/app/fleet')}> + <FormattedMessage + id="xpack.fleet.epm.packageDetailsSecurityRequiredCalloutDescriptionGuideLink" + defaultMessage="steps in this guide" + /> + </a> + ), + }} + /> + </EuiCallOut> + <EuiSpacer /> + </> + ) : undefined; return ( <WithHeaderLayout leftColumn={headerLeftContent} rightColumn={headerRightContent} rightColumnGrow={false} + topContent={securityCallout} tabs={headerTabs} tabsClassName="fleet__epm__shiftNavTabs" > @@ -526,3 +598,16 @@ export function Detail() { </WithHeaderLayout> ); } + +type EuiButtonPropsFull = Parameters<typeof EuiButton>[0]; + +const EuiButtonWithTooltip: React.FC<EuiButtonPropsFull & { tooltip?: Partial<EuiToolTipProps> }> = + ({ tooltip: tooltipProps, ...buttonProps }) => { + return tooltipProps ? ( + <EuiToolTip {...tooltipProps}> + <EuiButton {...buttonProps} /> + </EuiToolTip> + ) : ( + <EuiButton {...buttonProps} /> + ); + }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.test.tsx index 8872c61299093..6cb9aab005e77 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.test.tsx @@ -13,7 +13,12 @@ import { createIntegrationsTestRendererMock } from '../../../../../../../../mock import { PackagePolicyAgentsCell } from './package_policy_agents_cell'; -function renderCell({ agentCount = 0, agentPolicyId = '123', onAddAgent = () => {} }) { +function renderCell({ + agentCount = 0, + agentPolicyId = '123', + onAddAgent = () => {}, + hasHelpPopover = false, +}) { const renderer = createIntegrationsTestRendererMock(); return renderer.render( @@ -21,6 +26,7 @@ function renderCell({ agentCount = 0, agentPolicyId = '123', onAddAgent = () => agentCount={agentCount} agentPolicyId={agentPolicyId} onAddAgent={onAddAgent} + hasHelpPopover={hasHelpPopover} /> ); } @@ -40,4 +46,25 @@ describe('PackagePolicyAgentsCell', () => { expect(utils.queryByText('9999')).toBeInTheDocument(); }); }); + + test('it should display help popover if count is 0 and hasHelpPopover=true', async () => { + const utils = renderCell({ agentCount: 0, hasHelpPopover: true }); + await act(async () => { + expect(utils.queryByText('9999')).not.toBeInTheDocument(); + expect(utils.queryByText('Add agent')).toBeInTheDocument(); + expect( + utils.container.querySelector('[data-test-subj="addAgentHelpPopover"]') + ).toBeInTheDocument(); + }); + }); + test('it should not display help popover if count is > 0 and hasHelpPopover=true', async () => { + const utils = renderCell({ agentCount: 9999, hasHelpPopover: true }); + await act(async () => { + expect(utils.queryByText('9999')).toBeInTheDocument(); + expect(utils.queryByText('Add agent')).not.toBeInTheDocument(); + expect( + utils.container.querySelector('[data-test-subj="addAgentHelpPopover"]') + ).not.toBeInTheDocument(); + }); + }); }); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.tsx index 37543e7e5ae1b..e70d10e735571 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/components/package_policy_agents_cell.tsx @@ -5,20 +5,43 @@ * 2.0. */ -import React from 'react'; +import React, { useState } from 'react'; import { EuiButton } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { LinkedAgentCount } from '../../../../../../components'; +import { LinkedAgentCount, AddAgentHelpPopover } from '../../../../../../components'; + +const AddAgentButton = ({ onAddAgent }: { onAddAgent: () => void }) => ( + <EuiButton iconType="plusInCircle" data-test-subj="addAgentButton" onClick={onAddAgent}> + <FormattedMessage + id="xpack.fleet.epm.packageDetails.integrationList.addAgent" + defaultMessage="Add agent" + /> + </EuiButton> +); + +const AddAgentButtonWithPopover = ({ onAddAgent }: { onAddAgent: () => void }) => { + const button = <AddAgentButton onAddAgent={onAddAgent} />; + const [isHelpOpen, setIsHelpOpen] = useState<boolean>(true); + return ( + <AddAgentHelpPopover + button={button} + isOpen={isHelpOpen} + closePopover={() => setIsHelpOpen(false)} + /> + ); +}; export const PackagePolicyAgentsCell = ({ agentPolicyId, agentCount = 0, onAddAgent, + hasHelpPopover = false, }: { agentPolicyId: string; agentCount?: number; + hasHelpPopover?: boolean; onAddAgent: () => void; }) => { if (agentCount > 0) { @@ -31,12 +54,9 @@ export const PackagePolicyAgentsCell = ({ ); } - return ( - <EuiButton iconType="plusInCircle" data-test-subj="addAgentButton" onClick={onAddAgent}> - <FormattedMessage - id="xpack.fleet.epm.packageDetails.integrationList.addAgent" - defaultMessage="Add agent" - /> - </EuiButton> - ); + if (!hasHelpPopover) { + return <AddAgentButton onAddAgent={onAddAgent} />; + } + + return <AddAgentButtonWithPopover onAddAgent={onAddAgent} />; }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx index 304bdd621b1b2..2a7cab929211a 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx @@ -81,6 +81,10 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps () => queryParams.get('addAgentToPolicyId'), [queryParams] ); + const showAddAgentHelpForPolicyId = useMemo( + () => queryParams.get('showAddAgentHelpForPolicyId'), + [queryParams] + ); const [flyoutOpenForPolicyId, setFlyoutOpenForPolicyId] = useState<string | null>( agentPolicyIdFromParams ); @@ -294,6 +298,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps agentPolicyId={agentPolicy.id} agentCount={agentPolicy.agents} onAddAgent={() => setFlyoutOpenForPolicyId(agentPolicy.id)} + hasHelpPopover={showAddAgentHelpForPolicyId === agentPolicy.id} /> ); }, @@ -321,7 +326,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps }, }, ], - [getHref, viewDataStep] + [getHref, showAddAgentHelpForPolicyId, viewDataStep] ); const noItemsMessage = useMemo(() => { diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index 8aef9121bf67d..91b557d0db5b6 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -5,9 +5,10 @@ * 2.0. */ -import React, { memo, useMemo } from 'react'; +import React, { memo, useMemo, useState } from 'react'; import { useLocation, useHistory, useParams } from 'react-router-dom'; -import { i18n } from '@kbn/i18n'; +import _ from 'lodash'; +import { EuiHorizontalRule, EuiFlexItem } from '@elastic/eui'; import { pagePathGetters } from '../../../../constants'; import { @@ -26,30 +27,56 @@ import type { CustomIntegration } from '../../../../../../../../../../src/plugin import type { PackageListItem } from '../../../../types'; -import type { IntegrationCategory } from '../../../../../../../../../../src/plugins/custom_integrations/common'; +import type { IntegrationCardItem } from '../../../../../../../common/types/models'; -import { useMergeEprPackagesWithReplacements } from '../../../../../../hooks/use_merge_epr_with_replacements'; +import { useMergeEprPackagesWithReplacements } from '../../../../hooks/use_merge_epr_with_replacements'; -import { mergeAndReplaceCategoryCounts } from './util'; -import { CategoryFacets } from './category_facets'; +import type { IntegrationPreferenceType } from '../../components/integration_preference'; +import { IntegrationPreference } from '../../components/integration_preference'; + +import { mergeCategoriesAndCount } from './util'; +import { ALL_CATEGORY, CategoryFacets } from './category_facets'; import type { CategoryFacet } from './category_facets'; import type { CategoryParams } from '.'; import { getParams, categoryExists, mapToCard } from '.'; +function getAllCategoriesFromIntegrations(pkg: PackageListItem) { + if (!doesPackageHaveIntegrations(pkg)) { + return pkg.categories; + } + + const allCategories = pkg.policy_templates?.reduce((accumulator, integration) => { + return [...accumulator, ...(integration.categories || [])]; + }, pkg.categories || []); + + return _.uniq(allCategories); +} + // Packages can export multiple integrations, aka `policy_templates` // In the case where packages ship >1 `policy_templates`, we flatten out the // list of packages by bringing all integrations to top-level so that // each integration is displayed as its own tile const packageListToIntegrationsList = (packages: PackageList): PackageList => { return packages.reduce((acc: PackageList, pkg) => { - const { policy_templates: policyTemplates = [], ...restOfPackage } = pkg; + const { + policy_templates: policyTemplates = [], + categories: topCategories = [], + ...restOfPackage + } = pkg; + + const topPackage = { + ...restOfPackage, + categories: getAllCategoriesFromIntegrations(pkg), + }; + return [ ...acc, - restOfPackage, + topPackage, ...(doesPackageHaveIntegrations(pkg) ? policyTemplates.map((integration) => { - const { name, title, description, icons } = integration; + const { name, title, description, icons, categories = [] } = integration; + const allCategories = [...topCategories, ...categories]; return { ...restOfPackage, id: `${restOfPackage}-${name}`, @@ -57,6 +84,7 @@ const packageListToIntegrationsList = (packages: PackageList): PackageList => { title, description, icons: icons || restOfPackage.icons, + categories: _.uniq(allCategories), }; }) : []), @@ -64,13 +92,10 @@ const packageListToIntegrationsList = (packages: PackageList): PackageList => { }, []); }; -const title = i18n.translate('xpack.fleet.epmList.allTitle', { - defaultMessage: 'Browse by category', -}); - // TODO: clintandrewhall - this component is hard to test due to the hooks, particularly those that use `http` // or `location` to load data. Ideally, we'll split this into "connected" and "pure" components. export const AvailablePackages: React.FC = memo(() => { + const [preference, setPreference] = useState<IntegrationPreferenceType>('recommended'); useBreadcrumbs('integrations_all'); const { selectedCategory, searchParam } = getParams( @@ -79,7 +104,6 @@ export const AvailablePackages: React.FC = memo(() => { ); const history = useHistory(); - const { getHref, getAbsolutePath } = useLink(); function setSelectedCategory(categoryId: string) { @@ -92,118 +116,106 @@ export const AvailablePackages: React.FC = memo(() => { function setSearchTerm(search: string) { // Use .replace so the browser's back button is not tied to single keystroke - history.replace( - pagePathGetters.integrations_all({ category: selectedCategory, searchTerm: search })[1] - ); + history.replace(pagePathGetters.integrations_all({ searchTerm: search })[1]); } - const { data: allCategoryPackagesRes, isLoading: isLoadingAllPackages } = useGetPackages({ + const { data: eprPackages, isLoading: isLoadingAllPackages } = useGetPackages({ category: '', }); - const { data: categoryPackagesRes, isLoading: isLoadingCategoryPackages } = useGetPackages({ - category: selectedCategory, - }); - - const { data: categoriesRes, isLoading: isLoadingCategories } = useGetCategories({ - include_policy_templates: true, - }); - - const eprPackages = useMemo( - () => packageListToIntegrationsList(categoryPackagesRes?.response || []), - [categoryPackagesRes] - ); - - const allEprPackages = useMemo( - () => packageListToIntegrationsList(allCategoryPackagesRes?.response || []), - [allCategoryPackagesRes] + const eprIntegrationList = useMemo( + () => packageListToIntegrationsList(eprPackages?.response || []), + [eprPackages] ); const { value: replacementCustomIntegrations } = useGetReplacementCustomIntegrations(); const mergedEprPackages: Array<PackageListItem | CustomIntegration> = useMergeEprPackagesWithReplacements( - eprPackages || [], - replacementCustomIntegrations || [], - selectedCategory as IntegrationCategory + preference === 'beats' ? [] : eprIntegrationList, + preference === 'agent' ? [] : replacementCustomIntegrations || [] ); const { loading: isLoadingAppendCustomIntegrations, value: appendCustomIntegrations } = useGetAppendCustomIntegrations(); - const filteredAddableIntegrations = appendCustomIntegrations - ? appendCustomIntegrations.filter((integration: CustomIntegration) => { - if (!selectedCategory) { - return true; - } - return integration.categories.indexOf(selectedCategory as IntegrationCategory) >= 0; - }) - : []; - const eprAndCustomPackages: Array<CustomIntegration | PackageListItem> = [ ...mergedEprPackages, - ...filteredAddableIntegrations, + ...(appendCustomIntegrations || []), ]; - eprAndCustomPackages.sort((a, b) => { + const cards: IntegrationCardItem[] = eprAndCustomPackages.map((item) => { + return mapToCard(getAbsolutePath, getHref, item); + }); + + cards.sort((a, b) => { return a.title.localeCompare(b.title); }); + const { data: eprCategories, isLoading: isLoadingCategories } = useGetCategories({ + include_policy_templates: true, + }); + const categories = useMemo(() => { const eprAndCustomCategories: CategoryFacet[] = - isLoadingCategories || - isLoadingAppendCustomIntegrations || - !appendCustomIntegrations || - !categoriesRes + isLoadingCategories || !eprCategories ? [] - : mergeAndReplaceCategoryCounts( - categoriesRes.response as CategoryFacet[], - appendCustomIntegrations + : mergeCategoriesAndCount( + eprCategories.response as Array<{ id: string; title: string; count: number }>, + cards ); - return [ { - id: '', - count: (allEprPackages?.length || 0) + (appendCustomIntegrations?.length || 0), + ...ALL_CATEGORY, + count: cards.length, }, ...(eprAndCustomCategories ? eprAndCustomCategories : []), ] as CategoryFacet[]; - }, [ - allEprPackages?.length, - appendCustomIntegrations, - categoriesRes, - isLoadingAppendCustomIntegrations, - isLoadingCategories, - ]); + }, [cards, eprCategories, isLoadingCategories]); if (!isLoadingCategories && !categoryExists(selectedCategory, categories)) { history.replace(pagePathGetters.integrations_all({ category: '', searchTerm: searchParam })[1]); return null; } - const controls = categories ? ( - <CategoryFacets - showCounts={false} - isLoading={isLoadingCategories || isLoadingAllPackages || isLoadingAppendCustomIntegrations} - categories={categories} - selectedCategory={selectedCategory} - onCategoryChange={({ id }: CategoryFacet) => { - setSelectedCategory(id); - }} - /> - ) : null; + let controls = [ + <EuiFlexItem grow={false}> + <EuiHorizontalRule margin="m" /> + <IntegrationPreference initialType={preference} onChange={setPreference} />, + </EuiFlexItem>, + ]; - const cards = eprAndCustomPackages.map((item) => { - return mapToCard(getAbsolutePath, getHref, item); + if (categories) { + controls = [ + <EuiFlexItem className="eui-yScrollWithShadows"> + <CategoryFacets + isLoading={ + isLoadingCategories || isLoadingAllPackages || isLoadingAppendCustomIntegrations + } + categories={categories} + selectedCategory={selectedCategory} + onCategoryChange={({ id }) => { + setSelectedCategory(id); + }} + /> + </EuiFlexItem>, + ...controls, + ]; + } + + const filteredCards = cards.filter((c) => { + if (selectedCategory === '') { + return true; + } + return c.categories.includes(selectedCategory); }); return ( <PackageListGrid - isLoading={isLoadingCategoryPackages} - title={title} + isLoading={isLoadingAllPackages} controls={controls} initialSearch={searchParam} - list={cards} + list={filteredCards} setSelectedCategory={setSelectedCategory} onSearchChange={setSearchTerm} showMissingIntegrationMessage diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx index 3eba17d6627a1..0b17d17e19343 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx @@ -11,18 +11,21 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Loading } from '../../../../components'; -import type { IntegrationCategoryCount } from '../../../../../../../../../../src/plugins/custom_integrations/common'; -import { INTEGRATION_CATEGORY_DISPLAY } from '../../../../../../../../../../src/plugins/custom_integrations/common'; -interface ALL_CATEGORY { - id: ''; +export interface CategoryFacet { count: number; + id: string; + title: string; } -export type CategoryFacet = IntegrationCategoryCount | ALL_CATEGORY; +export const ALL_CATEGORY = { + id: '', + title: i18n.translate('xpack.fleet.epmList.allPackagesFilterLinkText', { + defaultMessage: 'All categories', + }), +}; export interface Props { - showCounts: boolean; isLoading?: boolean; categories: CategoryFacet[]; selectedCategory: string; @@ -30,7 +33,6 @@ export interface Props { } export function CategoryFacets({ - showCounts, isLoading, categories, selectedCategory, @@ -42,28 +44,15 @@ export function CategoryFacets({ <Loading /> ) : ( categories.map((category) => { - let title; - - if (category.id === 'updates_available') { - title = i18n.translate('xpack.fleet.epmList.updatesAvailableFilterLinkText', { - defaultMessage: 'Updates available', - }); - } else if (category.id === '') { - title = i18n.translate('xpack.fleet.epmList.allPackagesFilterLinkText', { - defaultMessage: 'All', - }); - } else { - title = INTEGRATION_CATEGORY_DISPLAY[category.id]; - } return ( <EuiFacetButton isSelected={category.id === selectedCategory} key={category.id} id={category.id} - quantity={showCounts ? category.count : undefined} + quantity={category.count} onClick={() => onCategoryChange(category)} > - {title} + {category.title} </EuiFacetButton> ); }) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/home.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/home.stories.tsx index a95a6b750cddc..5526935ef38e6 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/home.stories.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/home.stories.tsx @@ -14,7 +14,6 @@ import { INTEGRATIONS_ROUTING_PATHS } from '../../../../constants'; import { EPMHomePage as Component } from '.'; export default { - component: Component, title: 'Sections/EPM/Home', }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx index bbebf9e90b16c..2d1077f586a1a 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx @@ -12,6 +12,7 @@ import type { DynamicPage, DynamicPagePathValues, StaticPage } from '../../../.. import { INTEGRATIONS_ROUTING_PATHS, INTEGRATIONS_SEARCH_QUERYPARAM } from '../../../../constants'; import { DefaultLayout } from '../../../../layouts'; +import type { IntegrationCategory } from '../../../../../../../../../../src/plugins/custom_integrations/common'; import type { CustomIntegration } from '../../../../../../../../../../src/plugins/custom_integrations/common'; import type { PackageListItem } from '../../../../types'; @@ -31,7 +32,10 @@ export const getParams = (params: CategoryParams, search: string) => { const selectedCategory = category || ''; const queryParams = new URLSearchParams(search); const searchParam = queryParams.get(INTEGRATIONS_SEARCH_QUERYPARAM) || ''; - return { selectedCategory, searchParam }; + return { selectedCategory, searchParam } as { + selectedCategory: IntegrationCategory & ''; + searchParam: string; + }; }; export const categoryExists = (category: string, categories: CategoryFacet[]) => { @@ -72,6 +76,7 @@ export const mapToCard = ( name: 'name' in item ? item.name || '' : '', version: 'version' in item ? item.version || '' : '', release: 'release' in item ? item.release : undefined, + categories: ((item.categories || []) as string[]).filter((c: string) => !!c), }; }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/installed_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/installed_packages.tsx index 404e8820f90b7..efcdb7b169edf 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/installed_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/installed_packages.tsx @@ -23,6 +23,7 @@ import { CategoryFacets } from './category_facets'; import type { CategoryParams } from '.'; import { getParams, categoryExists, mapToCard } from '.'; +import { ALL_CATEGORY } from './category_facets'; const AnnouncementLink = () => { const { docLinks } = useStartServices(); @@ -114,12 +115,15 @@ export const InstalledPackages: React.FC = memo(() => { const categories: CategoryFacet[] = useMemo( () => [ { - id: '', + ...ALL_CATEGORY, count: allInstalledPackages.length, }, { id: 'updates_available', count: updatablePackages.length, + title: i18n.translate('xpack.fleet.epmList.updatesAvailableFilterLinkText', { + defaultMessage: 'Updates available', + }), }, ], [allInstalledPackages.length, updatablePackages.length] @@ -135,7 +139,6 @@ export const InstalledPackages: React.FC = memo(() => { const controls = ( <CategoryFacets - showCounts={true} categories={categories} selectedCategory={selectedCategory} onCategoryChange={({ id }: CategoryFacet) => setSelectedCategory(id)} diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts index 53a62555650ab..70902b2bc1897 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts @@ -5,46 +5,57 @@ * 2.0. */ -import type { - CustomIntegration, - IntegrationCategory, -} from '../../../../../../../../../../src/plugins/custom_integrations/common'; +import type { IntegrationCategory } from '../../../../../../../../../../src/plugins/custom_integrations/common'; +import { INTEGRATION_CATEGORY_DISPLAY } from '../../../../../../../../../../src/plugins/custom_integrations/common'; + +import type { IntegrationCardItem } from '../../../../../../../common/types/models'; import type { CategoryFacet } from './category_facets'; -export function mergeAndReplaceCategoryCounts( - eprCounts: CategoryFacet[], - addableIntegrations: CustomIntegration[] +export function mergeCategoriesAndCount( + eprCategoryList: Array<{ id: string; title: string; count: number }>, // EPR-categories from backend call to EPR + cards: IntegrationCardItem[] ): CategoryFacet[] { - const merged: CategoryFacet[] = []; + const facets: CategoryFacet[] = []; - const addIfMissing = (category: string, count: number) => { - const match = merged.find((c) => { + const addIfMissing = (category: string, count: number, title: string) => { + const match = facets.find((c) => { return c.id === category; }); if (match) { match.count += count; } else { - merged.push({ - id: category as IntegrationCategory, + facets.push({ + id: category, count, + title, }); } }; - eprCounts.forEach((facet) => { - addIfMissing(facet.id, facet.count); + // Seed the list with the dynamic categories + eprCategoryList.forEach((facet) => { + addIfMissing(facet.id, 0, facet.title); }); - addableIntegrations.forEach((integration) => { - integration.categories.forEach((cat) => { - addIfMissing(cat, 1); + + // Count all the categories + cards.forEach((integration) => { + integration.categories.forEach((cat: string) => { + const title = INTEGRATION_CATEGORY_DISPLAY[cat as IntegrationCategory] + ? INTEGRATION_CATEGORY_DISPLAY[cat as IntegrationCategory] + : cat; + addIfMissing(cat, 1, title); }); }); - merged.sort((a, b) => { + const filledFacets = facets.filter((facet) => { + return facet.count > 0; + }); + + filledFacets.sort((a, b) => { return a.id.localeCompare(b.id); }); - return merged; + return filledFacets; } diff --git a/x-pack/plugins/fleet/public/components/add_agent_help_popover.tsx b/x-pack/plugins/fleet/public/components/add_agent_help_popover.tsx new file mode 100644 index 0000000000000..e47070fdc7b99 --- /dev/null +++ b/x-pack/plugins/fleet/public/components/add_agent_help_popover.tsx @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { ReactElement } from 'react'; +import React from 'react'; + +import { FormattedMessage } from '@kbn/i18n/react'; + +import type { NoArgCallback } from '@elastic/eui'; +import { EuiTourStep, EuiLink, EuiText } from '@elastic/eui'; + +import { useStartServices } from '../hooks'; + +export const AddAgentHelpPopover = ({ + button, + isOpen, + offset, + closePopover, +}: { + button: ReactElement; + isOpen: boolean; + offset?: number; + closePopover: NoArgCallback<void>; +}) => { + const { docLinks } = useStartServices(); + + const optionalProps: { offset?: number } = {}; + + if (offset !== undefined) { + optionalProps.offset = offset; // offset being present in props sets it to 0 so only add if specified + } + + return ( + <EuiTourStep + {...optionalProps} + content={ + <EuiText size="m" style={{ width: 302 }}> + <FormattedMessage + id="xpack.fleet.addAgentHelpPopover.popoverBody" + defaultMessage="For integrations to work successfully, add {elasticAgent} to your host to collect data and send it to Elastic Stack. {learnMoreLink}" + values={{ + elasticAgent: <strong>Elastic Agent</strong>, + learnMoreLink: ( + <EuiLink target="_blank" external href={docLinks.links.fleet.elasticAgent}> + <FormattedMessage + id="xpack.fleet.addAgentHelpPopover.documentationLink" + defaultMessage="Learn more about Elastic Agent." + /> + </EuiLink> + ), + }} + /> + </EuiText> + } + isStepOpen={isOpen} + minWidth={300} + onFinish={() => {}} + step={1} + stepsTotal={1} + title={ + <FormattedMessage + id="xpack.fleet.addAgentHelpPopover.title" + defaultMessage="Don't forget to add the agent to your host" + /> + } + anchorPosition="downCenter" + subtitle={null} + data-test-subj="addAgentHelpPopover" + footerAction={ + <EuiLink + onClick={() => { + closePopover(); + }} + > + <FormattedMessage + id="xpack.fleet.addAgentHelpPopover.footActionButton" + defaultMessage="Got it" + /> + </EuiLink> + } + > + {button} + </EuiTourStep> + ); +}; diff --git a/x-pack/plugins/fleet/public/components/header.tsx b/x-pack/plugins/fleet/public/components/header.tsx index 80cebe3b0b304..2a8b20240a4f6 100644 --- a/x-pack/plugins/fleet/public/components/header.tsx +++ b/x-pack/plugins/fleet/public/components/header.tsx @@ -43,6 +43,7 @@ export interface HeaderProps { leftColumn?: JSX.Element; rightColumn?: JSX.Element; rightColumnGrow?: EuiFlexItemProps['grow']; + topContent?: JSX.Element; tabs?: Array<Omit<EuiTabProps, 'name'> & { name?: JSX.Element | string }>; tabsClassName?: string; 'data-test-subj'?: string; @@ -61,6 +62,7 @@ export const Header: React.FC<HeaderProps> = ({ leftColumn, rightColumn, rightColumnGrow, + topContent, tabs, maxWidth, tabsClassName, @@ -68,6 +70,7 @@ export const Header: React.FC<HeaderProps> = ({ }) => ( <Container data-test-subj={dataTestSubj}> <Wrapper maxWidth={maxWidth}> + {topContent} <HeaderColumns leftColumn={leftColumn} rightColumn={rightColumn} diff --git a/x-pack/plugins/fleet/public/components/home_integration/tutorial_module_notice.tsx b/x-pack/plugins/fleet/public/components/home_integration/tutorial_module_notice.tsx index 6b9b441551a56..24d9dc8e2c100 100644 --- a/x-pack/plugins/fleet/public/components/home_integration/tutorial_module_notice.tsx +++ b/x-pack/plugins/fleet/public/components/home_integration/tutorial_module_notice.tsx @@ -7,7 +7,8 @@ import React, { memo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiText, EuiLink, EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EuiText, EuiLink, EuiSpacer, EuiIcon } from '@elastic/eui'; import type { TutorialModuleNoticeComponent } from 'src/plugins/home/public'; import { useGetPackages, useLink, useCapabilities } from '../../hooks'; @@ -31,16 +32,20 @@ const TutorialModuleNotice: TutorialModuleNoticeComponent = memo(({ moduleName } <p> <FormattedMessage id="xpack.fleet.homeIntegration.tutorialModule.noticeText" - defaultMessage="{notePrefix} a newer version of this module is {availableAsIntegrationLink}. + defaultMessage="{notePrefix} A newer version of this module is {availableAsIntegrationLink}. To learn more about integrations and the new Elastic Agent, read our {blogPostLink}." values={{ notePrefix: ( - <strong> - <FormattedMessage - id="xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix" - defaultMessage="Note:" - /> - </strong> + <EuiIcon + type="iInCircle" + style={{ verticalAlign: 'baseline' }} + aria-label={i18n.translate( + 'xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix', + { + defaultMessage: 'Note', + } + )} + /> ), availableAsIntegrationLink: ( <EuiLink diff --git a/x-pack/plugins/fleet/public/components/index.ts b/x-pack/plugins/fleet/public/components/index.ts index dca0a92076180..3252315312d02 100644 --- a/x-pack/plugins/fleet/public/components/index.ts +++ b/x-pack/plugins/fleet/public/components/index.ts @@ -19,6 +19,7 @@ export { AgentPolicyPackageBadges } from './agent_policy_package_badges'; export { DangerEuiContextMenuItem } from './danger_eui_context_menu_item'; export { PackagePolicyDeleteProvider } from './package_policy_delete_provider'; export { PackagePolicyActionsMenu } from './package_policy_actions_menu'; +export { AddAgentHelpPopover } from './add_agent_help_popover'; export * from './link_and_revision'; export * from './settings_flyout'; export * from './agent_enrollment_flyout'; diff --git a/x-pack/plugins/fleet/public/components/package_icon.tsx b/x-pack/plugins/fleet/public/components/package_icon.tsx index 7a2a9f1091301..b77a7bd082d9a 100644 --- a/x-pack/plugins/fleet/public/components/package_icon.tsx +++ b/x-pack/plugins/fleet/public/components/package_icon.tsx @@ -23,9 +23,9 @@ export const CardIcon: React.FunctionComponent<UsePackageIconType & Omit<EuiIcon ) => { const { icons } = props; if (icons && icons.length === 1 && icons[0].type === 'eui') { - return <EuiIcon size={'xl'} type={icons[0].src} />; + return <EuiIcon size={'xl'} type={icons[0].src} {...props} />; } else if (icons && icons.length === 1 && icons[0].type === 'svg') { - return <EuiIcon size={'xl'} type={icons[0].src} />; + return <EuiIcon size={'xl'} type={icons[0].src} {...props} />; } else { return <PackageIcon {...props} />; } diff --git a/x-pack/plugins/fleet/public/hooks/use_request/app.ts b/x-pack/plugins/fleet/public/hooks/use_request/app.ts index c84dd0fd15b44..c4a0f94869827 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/app.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/app.ts @@ -8,7 +8,7 @@ import { appRoutesService } from '../../services'; import type { CheckPermissionsResponse, GenerateServiceTokenResponse } from '../../types'; -import { sendRequest } from './use_request'; +import { sendRequest, useRequest } from './use_request'; export const sendGetPermissionsCheck = () => { return sendRequest<CheckPermissionsResponse>({ @@ -23,3 +23,10 @@ export const sendGenerateServiceToken = () => { method: 'post', }); }; + +export const usePermissionCheck = () => { + return useRequest<CheckPermissionsResponse>({ + path: appRoutesService.getCheckPermissionsPath(), + method: 'get', + }); +}; diff --git a/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx b/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx index d0724545ee902..a0a9ef405540a 100644 --- a/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx +++ b/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx @@ -41,6 +41,7 @@ export interface TestRenderer { kibanaVersion: string; AppWrapper: React.FC<any>; render: UiRender; + setHeaderActionMenu: Function; } export const createFleetTestRendererMock = (): TestRenderer => { @@ -55,6 +56,7 @@ export const createFleetTestRendererMock = (): TestRenderer => { config: createConfigurationMock(), startInterface: createStartMock(extensions), kibanaVersion: '8.0.0', + setHeaderActionMenu: jest.fn(), AppWrapper: memo(({ children }) => { return ( <FleetAppContext @@ -96,6 +98,7 @@ export const createIntegrationsTestRendererMock = (): TestRenderer => { config: createConfigurationMock(), startInterface: createStartMock(extensions), kibanaVersion: '8.0.0', + setHeaderActionMenu: jest.fn(), AppWrapper: memo(({ children }) => { return ( <IntegrationsAppContext @@ -106,6 +109,7 @@ export const createIntegrationsTestRendererMock = (): TestRenderer => { kibanaVersion={testRendererMocks.kibanaVersion} extensions={extensions} routerHistory={testRendererMocks.history} + setHeaderActionMenu={() => {}} > {children} </IntegrationsAppContext> diff --git a/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts b/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts index f78fe58a6ad88..0bf0213905e72 100644 --- a/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts +++ b/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts @@ -10,6 +10,7 @@ import { licensingMock } from '../../../licensing/public/mocks'; import { homePluginMock } from '../../../../../src/plugins/home/public/mocks'; import { navigationPluginMock } from '../../../../../src/plugins/navigation/public/mocks'; import { customIntegrationsMock } from '../../../../../src/plugins/custom_integrations/public/mocks'; +import { sharePluginMock } from '../../../../../src/plugins/share/public/mocks'; import type { MockedFleetSetupDeps, MockedFleetStartDeps } from './types'; @@ -27,5 +28,6 @@ export const createStartDepsMock = (): MockedFleetStartDeps => { data: dataPluginMock.createStartContract(), navigation: navigationPluginMock.createStartContract(), customIntegrations: customIntegrationsMock.createStart(), + share: sharePluginMock.createStartContract(), }; }; diff --git a/x-pack/plugins/fleet/public/plugin.ts b/x-pack/plugins/fleet/public/plugin.ts index d23bfcfe7b888..e1f263b0763e8 100644 --- a/x-pack/plugins/fleet/public/plugin.ts +++ b/x-pack/plugins/fleet/public/plugin.ts @@ -21,6 +21,8 @@ import type { CustomIntegrationsSetup, } from 'src/plugins/custom_integrations/public'; +import type { SharePluginStart } from 'src/plugins/share/public'; + import { DEFAULT_APP_CATEGORIES, AppNavLinkStatus } from '../../../../src/core/public'; import type { @@ -81,10 +83,12 @@ export interface FleetStartDeps { data: DataPublicPluginStart; navigation: NavigationPublicPluginStart; customIntegrations: CustomIntegrationsStart; + share: SharePluginStart; } export interface FleetStartServices extends CoreStart, FleetStartDeps { storage: Storage; + share: SharePluginStart; cloud?: CloudSetup; } @@ -134,6 +138,7 @@ export class FleetPlugin implements Plugin<FleetSetup, FleetStart, FleetSetupDep ...coreStartServices, ...startDepsServices, storage: this.storage, + cloud: deps.cloud, }; const { renderApp, teardownIntegrations } = await import('./applications/integrations'); const unmount = renderApp(startServices, params, config, kibanaVersion, extensions); diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index 43b455045e72b..0e7b335da6775 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -37,7 +37,8 @@ export const createAppContextStartContractMock = (): FleetAppContext => { data: dataPluginMock.createStartContract(), encryptedSavedObjectsStart: encryptedSavedObjectsMock.createStart(), savedObjects: savedObjectsServiceMock.createStartContract(), - security: securityMock.createStart(), + securitySetup: securityMock.createSetup(), + securityStart: securityMock.createStart(), logger: loggingSystemMock.create().get(), isProductionMode: true, configInitialValue: { diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index 6aad028666ee8..a706ca6a54fdc 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -37,6 +37,7 @@ import { AGENT_POLICY_SAVED_OBJECT_TYPE, PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGES_SAVED_OBJECT_TYPE, + ASSETS_SAVED_OBJECT_TYPE, AGENT_SAVED_OBJECT_TYPE, ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE, PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, @@ -103,7 +104,8 @@ export interface FleetAppContext { data: DataPluginStart; encryptedSavedObjectsStart?: EncryptedSavedObjectsPluginStart; encryptedSavedObjectsSetup?: EncryptedSavedObjectsPluginSetup; - security?: SecurityPluginStart; + securitySetup?: SecurityPluginSetup; + securityStart?: SecurityPluginStart; config$?: Observable<FleetConfigType>; configInitialValue: FleetConfigType; savedObjects: SavedObjectsServiceStart; @@ -122,6 +124,7 @@ const allSavedObjectTypes = [ AGENT_POLICY_SAVED_OBJECT_TYPE, PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGES_SAVED_OBJECT_TYPE, + ASSETS_SAVED_OBJECT_TYPE, AGENT_SAVED_OBJECT_TYPE, ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE, PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, @@ -164,14 +167,15 @@ export class FleetPlugin private licensing$!: Observable<ILicense>; private config$: Observable<FleetConfigType>; private configInitialValue: FleetConfigType; - private cloud: CloudSetup | undefined; - private logger: Logger | undefined; + private cloud?: CloudSetup; + private logger?: Logger; private isProductionMode: FleetAppContext['isProductionMode']; private kibanaVersion: FleetAppContext['kibanaVersion']; private kibanaBranch: FleetAppContext['kibanaBranch']; - private httpSetup: HttpServiceSetup | undefined; - private encryptedSavedObjectsSetup: EncryptedSavedObjectsPluginSetup | undefined; + private httpSetup?: HttpServiceSetup; + private securitySetup?: SecurityPluginSetup; + private encryptedSavedObjectsSetup?: EncryptedSavedObjectsPluginSetup; constructor(private readonly initializerContext: PluginInitializerContext) { this.config$ = this.initializerContext.config.create<FleetConfigType>(); @@ -187,6 +191,7 @@ export class FleetPlugin this.licensing$ = deps.licensing.license$; this.encryptedSavedObjectsSetup = deps.encryptedSavedObjects; this.cloud = deps.cloud; + this.securitySetup = deps.security; const config = this.configInitialValue; registerSavedObjects(core.savedObjects, deps.encryptedSavedObjects); @@ -233,6 +238,10 @@ export class FleetPlugin // Always register app routes for permissions checking registerAppRoutes(router); + // Allow read-only users access to endpoints necessary for Integrations UI + // Only some endpoints require superuser so we pass a raw IRouter here + registerEPMRoutes(router); + // For all the routes we enforce the user to have role superuser const routerSuperuserOnly = makeRouterEnforcingSuperuser(router); // Register rest of routes only if security is enabled @@ -243,7 +252,6 @@ export class FleetPlugin registerOutputRoutes(routerSuperuserOnly); registerSettingsRoutes(routerSuperuserOnly); registerDataStreamRoutes(routerSuperuserOnly); - registerEPMRoutes(routerSuperuserOnly); registerPreconfigurationRoutes(routerSuperuserOnly); // Conditional config routes @@ -260,7 +268,8 @@ export class FleetPlugin data: plugins.data, encryptedSavedObjectsStart: plugins.encryptedSavedObjects, encryptedSavedObjectsSetup: this.encryptedSavedObjectsSetup, - security: plugins.security, + securitySetup: this.securitySetup, + securityStart: plugins.security, configInitialValue: this.configInitialValue, config$: this.config$, savedObjects: core.savedObjects, diff --git a/x-pack/plugins/fleet/server/routes/app/index.ts b/x-pack/plugins/fleet/server/routes/app/index.ts index f2fc6302c8ce5..43614f3a286b0 100644 --- a/x-pack/plugins/fleet/server/routes/app/index.ts +++ b/x-pack/plugins/fleet/server/routes/app/index.ts @@ -13,26 +13,35 @@ import type { CheckPermissionsResponse, GenerateServiceTokenResponse } from '../ import { defaultIngestErrorHandler, GenerateServiceTokenError } from '../../errors'; export const getCheckPermissionsHandler: RequestHandler = async (context, request, response) => { - const body: CheckPermissionsResponse = { success: true }; - try { - const security = await appContextService.getSecurity(); + const missingSecurityBody: CheckPermissionsResponse = { + success: false, + error: 'MISSING_SECURITY', + }; + + if (!appContextService.hasSecurity() || !appContextService.getSecurityLicense().isEnabled()) { + return response.ok({ body: missingSecurityBody }); + } else { + const security = appContextService.getSecurity(); const user = security.authc.getCurrentUser(request); + // Defensively handle situation where user is undefined (should only happen when ES security is disabled) + // This should be covered by the `getSecurityLicense().isEnabled()` check above, but we leave this for robustness. + if (!user) { + return response.ok({ + body: missingSecurityBody, + }); + } + if (!user?.roles.includes('superuser')) { - body.success = false; - body.error = 'MISSING_SUPERUSER_ROLE'; return response.ok({ - body, + body: { + success: false, + error: 'MISSING_SUPERUSER_ROLE', + } as CheckPermissionsResponse, }); } - return response.ok({ body: { success: true } }); - } catch (e) { - body.success = false; - body.error = 'MISSING_SECURITY'; - return response.ok({ - body, - }); + return response.ok({ body: { success: true } as CheckPermissionsResponse }); } }; diff --git a/x-pack/plugins/fleet/server/routes/epm/index.ts b/x-pack/plugins/fleet/server/routes/epm/index.ts index 684547dc1862c..0f49b3cfa772d 100644 --- a/x-pack/plugins/fleet/server/routes/epm/index.ts +++ b/x-pack/plugins/fleet/server/routes/epm/index.ts @@ -20,6 +20,7 @@ import { GetStatsRequestSchema, UpdatePackageRequestSchema, } from '../../types'; +import { enforceSuperUser } from '../security'; import { getCategoriesHandler, @@ -60,7 +61,7 @@ export const registerRoutes = (router: IRouter) => { { path: EPM_API_ROUTES.LIMITED_LIST_PATTERN, validate: false, - options: { tags: [`access:${PLUGIN_ID}`] }, + options: { tags: [`access:${PLUGIN_ID}-read`] }, }, getLimitedListHandler ); @@ -69,7 +70,7 @@ export const registerRoutes = (router: IRouter) => { { path: EPM_API_ROUTES.STATS_PATTERN, validate: GetStatsRequestSchema, - options: { tags: [`access:${PLUGIN_ID}`] }, + options: { tags: [`access:${PLUGIN_ID}-read`] }, }, getStatsHandler ); @@ -98,7 +99,7 @@ export const registerRoutes = (router: IRouter) => { validate: UpdatePackageRequestSchema, options: { tags: [`access:${PLUGIN_ID}-all`] }, }, - updatePackageHandler + enforceSuperUser(updatePackageHandler) ); router.post( @@ -107,7 +108,7 @@ export const registerRoutes = (router: IRouter) => { validate: InstallPackageFromRegistryRequestSchema, options: { tags: [`access:${PLUGIN_ID}-all`] }, }, - installPackageFromRegistryHandler + enforceSuperUser(installPackageFromRegistryHandler) ); router.post( @@ -116,7 +117,7 @@ export const registerRoutes = (router: IRouter) => { validate: BulkUpgradePackagesFromRegistryRequestSchema, options: { tags: [`access:${PLUGIN_ID}-all`] }, }, - bulkInstallPackagesFromRegistryHandler + enforceSuperUser(bulkInstallPackagesFromRegistryHandler) ); router.post( @@ -132,7 +133,7 @@ export const registerRoutes = (router: IRouter) => { }, }, }, - installPackageByUploadHandler + enforceSuperUser(installPackageByUploadHandler) ); router.delete( @@ -141,6 +142,6 @@ export const registerRoutes = (router: IRouter) => { validate: DeletePackageRequestSchema, options: { tags: [`access:${PLUGIN_ID}-all`] }, }, - deletePackageHandler + enforceSuperUser(deletePackageHandler) ); }; diff --git a/x-pack/plugins/fleet/server/routes/security.ts b/x-pack/plugins/fleet/server/routes/security.ts index 60011dcf3d33f..8efea34ed8164 100644 --- a/x-pack/plugins/fleet/server/routes/security.ts +++ b/x-pack/plugins/fleet/server/routes/security.ts @@ -13,6 +13,14 @@ export function enforceSuperUser<T1, T2, T3>( handler: RequestHandler<T1, T2, T3> ): RequestHandler<T1, T2, T3> { return function enforceSuperHandler(context, req, res) { + if (!appContextService.hasSecurity() || !appContextService.getSecurityLicense().isEnabled()) { + return res.forbidden({ + body: { + message: `Access to this API requires that security is enabled`, + }, + }); + } + const security = appContextService.getSecurity(); const user = security.authc.getCurrentUser(req); if (!user) { diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts index bd82989a9e828..c196054faf08c 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts @@ -53,7 +53,10 @@ describe('FleetSetupHandler', () => { ); await fleetSetupHandler(context, request, response); - const expectedBody: PostFleetSetupResponse = { isInitialized: true, nonFatalErrors: [] }; + const expectedBody: PostFleetSetupResponse = { + isInitialized: true, + nonFatalErrors: [], + }; expect(response.customError).toHaveBeenCalledTimes(0); expect(response.ok).toHaveBeenCalledWith({ body: expectedBody }); }); diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.ts index 6311b9d970d35..d24db96667d52 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.ts @@ -49,13 +49,21 @@ export const fleetSetupHandler: RequestHandler = async (context, request, respon const setupStatus = await setupFleet(soClient, esClient); const body: PostFleetSetupResponse = { ...setupStatus, - nonFatalErrors: setupStatus.nonFatalErrors.map((e) => { + nonFatalErrors: setupStatus.nonFatalErrors.flatMap((e) => { // JSONify the error object so it can be displayed properly in the UI - const error = e.error ?? e; - return { - name: error.name, - message: error.message, - }; + if ('error' in e) { + return { + name: e.error.name, + message: e.error.message, + }; + } else { + return e.errors.map((upgradePackagePolicyError: any) => { + return { + name: upgradePackagePolicyError.key, + message: upgradePackagePolicyError.message, + }; + }); + } }), }; diff --git a/x-pack/plugins/fleet/server/services/app_context.ts b/x-pack/plugins/fleet/server/services/app_context.ts index 1fb34a9a399eb..a1e6ef4545aef 100644 --- a/x-pack/plugins/fleet/server/services/app_context.ts +++ b/x-pack/plugins/fleet/server/services/app_context.ts @@ -22,7 +22,7 @@ import type { EncryptedSavedObjectsPluginSetup, } from '../../../encrypted_saved_objects/server'; -import type { SecurityPluginStart } from '../../../security/server'; +import type { SecurityPluginStart, SecurityPluginSetup } from '../../../security/server'; import type { FleetConfigType } from '../../common'; import type { ExternalCallback, @@ -39,7 +39,8 @@ class AppContextService { private encryptedSavedObjectsSetup: EncryptedSavedObjectsPluginSetup | undefined; private data: DataPluginStart | undefined; private esClient: ElasticsearchClient | undefined; - private security: SecurityPluginStart | undefined; + private securitySetup: SecurityPluginSetup | undefined; + private securityStart: SecurityPluginStart | undefined; private config$?: Observable<FleetConfigType>; private configSubject$?: BehaviorSubject<FleetConfigType>; private savedObjects: SavedObjectsServiceStart | undefined; @@ -56,7 +57,8 @@ class AppContextService { this.esClient = appContext.elasticsearch.client.asInternalUser; this.encryptedSavedObjects = appContext.encryptedSavedObjectsStart?.getClient(); this.encryptedSavedObjectsSetup = appContext.encryptedSavedObjectsSetup; - this.security = appContext.security; + this.securitySetup = appContext.securitySetup; + this.securityStart = appContext.securityStart; this.savedObjects = appContext.savedObjects; this.isProductionMode = appContext.isProductionMode; this.cloud = appContext.cloud; @@ -92,14 +94,21 @@ class AppContextService { } public getSecurity() { - if (!this.security) { + if (!this.hasSecurity()) { throw new Error('Security service not set.'); } - return this.security; + return this.securityStart!; + } + + public getSecurityLicense() { + if (!this.hasSecurity()) { + throw new Error('Security service not set.'); + } + return this.securitySetup!.license; } public hasSecurity() { - return !!this.security; + return !!this.securitySetup && !!this.securityStart; } public getCloud() { diff --git a/x-pack/plugins/fleet/server/services/epm/archive/cache.ts b/x-pack/plugins/fleet/server/services/epm/archive/cache.ts index 7f479dc5d6b63..676c3aa571a0f 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/cache.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/cache.ts @@ -67,3 +67,11 @@ export const setPackageInfo = ({ }; export const deletePackageInfo = (args: SharedKey) => packageInfoCache.delete(sharedKey(args)); + +export const clearPackageFileCache = (args: SharedKey) => { + const fileList = getArchiveFilelist(args) ?? []; + fileList.forEach((filePath) => { + deleteArchiveEntry(filePath); + }); + deleteArchiveFilelist(args); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/archive/index.ts b/x-pack/plugins/fleet/server/services/epm/archive/index.ts index b08ec815a394d..7c590eb1bcd39 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/index.ts @@ -16,6 +16,7 @@ import { setArchiveFilelist, deleteArchiveFilelist, deletePackageInfo, + clearPackageFileCache, } from './cache'; import type { SharedKey } from './cache'; import { getBufferExtractor } from './extract'; @@ -42,6 +43,9 @@ export async function unpackBufferToCache({ archiveBuffer: Buffer; installSource: InstallSource; }): Promise<string[]> { + // Make sure any buffers from previous installations from registry or upload are deleted first + clearPackageFileCache({ name, version }); + const entries = await unpackBufferEntries(archiveBuffer, contentType); const paths: string[] = []; entries.forEach((entry) => { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index d4f988e5fba8c..8d3c1fbe0daa4 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -53,7 +53,6 @@ export async function getPackages( }); // get the installed packages const packageSavedObjects = await getPackageSavedObjects(savedObjectsClient); - // filter out any internal packages const savedObjectsVisible = packageSavedObjects.saved_objects.filter( (o) => !o.attributes.internal @@ -70,7 +69,6 @@ export async function getPackages( } // Get package names for packages which cannot have more than one package policy on an agent policy -// Assume packages only export one policy template for now export async function getLimitedPackages(options: { savedObjectsClient: SavedObjectsClientContract; }): Promise<string[]> { diff --git a/x-pack/plugins/fleet/server/services/managed_package_policies.test.ts b/x-pack/plugins/fleet/server/services/managed_package_policies.test.ts index a53b1fe648905..52c1c71446d64 100644 --- a/x-pack/plugins/fleet/server/services/managed_package_policies.test.ts +++ b/x-pack/plugins/fleet/server/services/managed_package_policies.test.ts @@ -18,7 +18,7 @@ jest.mock('./app_context', () => { ...jest.requireActual('./app_context'), appContextService: { getLogger: jest.fn(() => { - return { debug: jest.fn() }; + return { error: jest.fn() }; }), }, }; @@ -27,7 +27,9 @@ jest.mock('./app_context', () => { describe('managed package policies', () => { afterEach(() => { (packagePolicyService.get as jest.Mock).mockReset(); + (packagePolicyService.getUpgradeDryRunDiff as jest.Mock).mockReset(); (getPackageInfo as jest.Mock).mockReset(); + (packagePolicyService.upgrade as jest.Mock).mockReset(); }); it('should not upgrade policies for non-managed package', async () => { @@ -54,6 +56,16 @@ describe('managed package policies', () => { } ); + (packagePolicyService.getUpgradeDryRunDiff as jest.Mock).mockImplementationOnce( + (savedObjectsClient: any, id: string) => { + return { + name: 'non-managed-package-policy', + diff: [{ id: 'foo' }, { id: 'bar' }], + hasErrors: false, + }; + } + ); + (getPackageInfo as jest.Mock).mockImplementationOnce( ({ savedObjectsClient, pkgName, pkgVersion }) => ({ name: pkgName, @@ -91,6 +103,16 @@ describe('managed package policies', () => { } ); + (packagePolicyService.getUpgradeDryRunDiff as jest.Mock).mockImplementationOnce( + (savedObjectsClient: any, id: string) => { + return { + name: 'non-managed-package-policy', + diff: [{ id: 'foo' }, { id: 'bar' }], + hasErrors: false, + }; + } + ); + (getPackageInfo as jest.Mock).mockImplementationOnce( ({ savedObjectsClient, pkgName, pkgVersion }) => ({ name: pkgName, @@ -103,4 +125,84 @@ describe('managed package policies', () => { expect(packagePolicyService.upgrade).toBeCalledWith(soClient, esClient, ['managed-package-id']); }); + + describe('when dry run reports conflicts', () => { + it('should return errors + diff without performing upgrade', async () => { + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + const soClient = savedObjectsClientMock.create(); + + (packagePolicyService.get as jest.Mock).mockImplementationOnce( + (savedObjectsClient: any, id: string) => { + return { + id, + inputs: {}, + version: '', + revision: 1, + updated_at: '', + updated_by: '', + created_at: '', + created_by: '', + package: { + name: 'conflicting-package', + title: 'Conflicting Package', + version: '0.0.1', + }, + }; + } + ); + + (packagePolicyService.getUpgradeDryRunDiff as jest.Mock).mockImplementationOnce( + (savedObjectsClient: any, id: string) => { + return { + name: 'conflicting-package-policy', + diff: [ + { id: 'foo' }, + { id: 'bar', errors: [{ key: 'some.test.value', message: 'Conflict detected' }] }, + ], + hasErrors: true, + }; + } + ); + + (getPackageInfo as jest.Mock).mockImplementationOnce( + ({ savedObjectsClient, pkgName, pkgVersion }) => ({ + name: pkgName, + version: pkgVersion, + keepPoliciesUpToDate: true, + }) + ); + + const result = await upgradeManagedPackagePolicies(soClient, esClient, [ + 'conflicting-package-policy', + ]); + + expect(result).toEqual([ + { + packagePolicyId: 'conflicting-package-policy', + diff: [ + { + id: 'foo', + }, + { + id: 'bar', + errors: [ + { + key: 'some.test.value', + message: 'Conflict detected', + }, + ], + }, + ], + errors: [ + { + key: 'some.test.value', + message: 'Conflict detected', + }, + ], + }, + ]); + + expect(packagePolicyService.upgrade).not.toBeCalled(); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/managed_package_policies.ts b/x-pack/plugins/fleet/server/services/managed_package_policies.ts index 73f85525f4c60..25e2482892712 100644 --- a/x-pack/plugins/fleet/server/services/managed_package_policies.ts +++ b/x-pack/plugins/fleet/server/services/managed_package_policies.ts @@ -7,12 +7,19 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server'; +import type { UpgradePackagePolicyDryRunResponseItem } from '../../common'; import { AUTO_UPDATE_PACKAGES } from '../../common'; import { appContextService } from './app_context'; -import { getPackageInfo } from './epm/packages'; +import { getInstallation, getPackageInfo } from './epm/packages'; import { packagePolicyService } from './package_policy'; +export interface UpgradeManagedPackagePoliciesResult { + packagePolicyId: string; + diff: UpgradePackagePolicyDryRunResponseItem['diff']; + errors: any; +} + /** * Upgrade any package policies for packages installed through setup that are denoted as `AUTO_UPGRADE` packages * or have the `keep_policies_up_to_date` flag set to `true` @@ -21,8 +28,8 @@ export const upgradeManagedPackagePolicies = async ( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, packagePolicyIds: string[] -) => { - const policyIdsToUpgrade: string[] = []; +): Promise<UpgradeManagedPackagePoliciesResult[]> => { + const results: UpgradeManagedPackagePoliciesResult[] = []; for (const packagePolicyId of packagePolicyIds) { const packagePolicy = await packagePolicyService.get(soClient, packagePolicyId); @@ -37,22 +44,50 @@ export const upgradeManagedPackagePolicies = async ( pkgVersion: packagePolicy.package.version, }); + const installedPackage = await getInstallation({ + savedObjectsClient: soClient, + pkgName: packagePolicy.package.name, + }); + + const isPolicyVersionAlignedWithInstalledVersion = + packageInfo.version === installedPackage?.version; + const shouldUpgradePolicies = - AUTO_UPDATE_PACKAGES.some((pkg) => pkg.name === packageInfo.name) || - packageInfo.keepPoliciesUpToDate; + !isPolicyVersionAlignedWithInstalledVersion && + (AUTO_UPDATE_PACKAGES.some((pkg) => pkg.name === packageInfo.name) || + packageInfo.keepPoliciesUpToDate); if (shouldUpgradePolicies) { - policyIdsToUpgrade.push(packagePolicy.id); - } - } - - if (policyIdsToUpgrade.length) { - appContextService - .getLogger() - .debug( - `Upgrading ${policyIdsToUpgrade.length} package policies: ${policyIdsToUpgrade.join(', ')}` + // Since upgrades don't report diffs/errors, we need to perform a dry run first in order + // to notify the user of any granular policy upgrade errors that occur during Fleet's + // preconfiguration check + const dryRunResults = await packagePolicyService.getUpgradeDryRunDiff( + soClient, + packagePolicyId ); - await packagePolicyService.upgrade(soClient, esClient, policyIdsToUpgrade); + if (dryRunResults.hasErrors) { + const errors = dryRunResults.diff?.[1].errors; + appContextService + .getLogger() + .error( + new Error( + `Error upgrading package policy ${packagePolicyId}: ${JSON.stringify(errors)}` + ) + ); + + results.push({ packagePolicyId, diff: dryRunResults.diff, errors }); + continue; + } + + try { + await packagePolicyService.upgrade(soClient, esClient, [packagePolicyId]); + results.push({ packagePolicyId, diff: dryRunResults.diff, errors: [] }); + } catch (error) { + results.push({ packagePolicyId, diff: dryRunResults.diff, errors: [error] }); + } + } } + + return results; }; diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts index d0ae995358632..102b059515151 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts @@ -503,6 +503,8 @@ describe('output preconfiguration', () => { beforeEach(() => { mockedOutputService.create.mockReset(); mockedOutputService.update.mockReset(); + mockedOutputService.delete.mockReset(); + mockedOutputService.getDefaultOutputId.mockReset(); mockedOutputService.getDefaultESHosts.mockReturnValue(['http://default-es:9200']); mockedOutputService.bulkGet.mockImplementation(async (soClient, id): Promise<Output[]> => { return [ @@ -537,6 +539,26 @@ describe('output preconfiguration', () => { expect(spyAgentPolicyServicBumpAllAgentPoliciesForOutput).not.toBeCalled(); }); + it('should delete existing default output if a new preconfigured output is added', async () => { + const soClient = savedObjectsClientMock.create(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + mockedOutputService.getDefaultOutputId.mockResolvedValue('default-output-123'); + await ensurePreconfiguredOutputs(soClient, esClient, [ + { + id: 'non-existing-default-output-1', + name: 'Output 1', + type: 'elasticsearch', + is_default: true, + hosts: ['http://test.fr'], + }, + ]); + + expect(mockedOutputService.delete).toBeCalled(); + expect(mockedOutputService.create).toBeCalled(); + expect(mockedOutputService.update).not.toBeCalled(); + expect(spyAgentPolicyServicBumpAllAgentPoliciesForOutput).not.toBeCalled(); + }); + it('should set default hosts if hosts is not set output that does not exists', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; @@ -572,6 +594,48 @@ describe('output preconfiguration', () => { expect(spyAgentPolicyServicBumpAllAgentPoliciesForOutput).toBeCalled(); }); + it('should delete default output if preconfigured output exists and another default output exists', async () => { + const soClient = savedObjectsClientMock.create(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); + mockedOutputService.getDefaultOutputId.mockResolvedValue('default-123'); + await ensurePreconfiguredOutputs(soClient, esClient, [ + { + id: 'existing-output-1', + is_default: true, + name: 'Output 1', + type: 'elasticsearch', + hosts: ['http://newhostichanged.co:9201'], // field that changed + }, + ]); + + expect(mockedOutputService.delete).toBeCalled(); + expect(mockedOutputService.create).not.toBeCalled(); + expect(mockedOutputService.update).toBeCalled(); + expect(spyAgentPolicyServicBumpAllAgentPoliciesForOutput).toBeCalled(); + }); + + it('should not delete default output if preconfigured default output exists and changed', async () => { + const soClient = savedObjectsClientMock.create(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); + mockedOutputService.getDefaultOutputId.mockResolvedValue('existing-output-1'); + await ensurePreconfiguredOutputs(soClient, esClient, [ + { + id: 'existing-output-1', + is_default: true, + name: 'Output 1', + type: 'elasticsearch', + hosts: ['http://newhostichanged.co:9201'], // field that changed + }, + ]); + + expect(mockedOutputService.delete).not.toBeCalled(); + expect(mockedOutputService.create).not.toBeCalled(); + expect(mockedOutputService.update).toBeCalled(); + expect(spyAgentPolicyServicBumpAllAgentPoliciesForOutput).toBeCalled(); + }); + const SCENARIOS: Array<{ name: string; data: PreconfiguredOutput }> = [ { name: 'no changes', diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index a444f8bdaa4da..3b322e1112d6a 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -35,13 +35,14 @@ import { agentPolicyService, addPackageToAgentPolicy } from './agent_policy'; import type { InputsOverride } from './package_policy'; import { overridePackageInputs } from './package_policy'; import { appContextService } from './app_context'; +import type { UpgradeManagedPackagePoliciesResult } from './managed_package_policies'; import { upgradeManagedPackagePolicies } from './managed_package_policies'; import { outputService } from './output'; interface PreconfigurationResult { policies: Array<{ id: string; updated_at: string }>; packages: string[]; - nonFatalErrors: PreconfigurationError[]; + nonFatalErrors: Array<PreconfigurationError | UpgradeManagedPackagePoliciesResult>; } function isPreconfiguredOutputDifferentFromCurrent( @@ -95,9 +96,21 @@ export async function ensurePreconfiguredOutputs( data.hosts = outputService.getDefaultESHosts(); } - if (!existingOutput) { + const isCreate = !existingOutput; + const isUpdateWithNewData = + existingOutput && isPreconfiguredOutputDifferentFromCurrent(existingOutput, data); + // If a default output already exists, delete it in favor of the preconfigured one + if (isCreate || isUpdateWithNewData) { + const defaultOutputId = await outputService.getDefaultOutputId(soClient); + + if (defaultOutputId && defaultOutputId !== output.id) { + await outputService.delete(soClient, defaultOutputId); + } + } + + if (isCreate) { await outputService.create(soClient, data, { id, overwrite: true }); - } else if (isPreconfiguredOutputDifferentFromCurrent(existingOutput, data)) { + } else if (isUpdateWithNewData) { await outputService.update(soClient, id, data); // Bump revision of all policies using that output if (outputData.is_default) { @@ -314,16 +327,15 @@ export async function ensurePreconfiguredPackagesAndPolicies( } } - try { - const fulfilledPolicyPackagePolicyIds = fulfilledPolicies.flatMap<string>( - ({ policy }) => policy?.package_policies as string[] - ); + const fulfilledPolicyPackagePolicyIds = fulfilledPolicies + .filter(({ policy }) => policy?.package_policies) + .flatMap<string>(({ policy }) => policy?.package_policies as string[]); - await upgradeManagedPackagePolicies(soClient, esClient, fulfilledPolicyPackagePolicyIds); - // Swallow errors that occur when upgrading - } catch (error) { - appContextService.getLogger().error(error); - } + const packagePolicyUpgradeResults = await upgradeManagedPackagePolicies( + soClient, + esClient, + fulfilledPolicyPackagePolicyIds + ); return { policies: fulfilledPolicies.map((p) => @@ -341,7 +353,7 @@ export async function ensurePreconfiguredPackagesAndPolicies( } ), packages: fulfilledPackages.map((pkg) => pkgToPkgKey(pkg)), - nonFatalErrors: [...rejectedPackages, ...rejectedPolicies], + nonFatalErrors: [...rejectedPackages, ...rejectedPolicies, ...packagePolicyUpgradeResults], }; } diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index 08c580d80c804..37d79c1bb691d 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -32,10 +32,13 @@ import { ensureDefaultComponentTemplate } from './epm/elasticsearch/template/ins import { getInstallations, installPackage } from './epm/packages'; import { isPackageInstalled } from './epm/packages/install'; import { pkgToPkgKey } from './epm/registry'; +import type { UpgradeManagedPackagePoliciesResult } from './managed_package_policies'; export interface SetupStatus { isInitialized: boolean; - nonFatalErrors: Array<PreconfigurationError | DefaultPackagesInstallationError>; + nonFatalErrors: Array< + PreconfigurationError | DefaultPackagesInstallationError | UpgradeManagedPackagePoliciesResult + >; } export async function setupFleet( diff --git a/x-pack/plugins/fleet/storybook/context/cloud.ts b/x-pack/plugins/fleet/storybook/context/cloud.ts new file mode 100644 index 0000000000000..bed72c8ac4db7 --- /dev/null +++ b/x-pack/plugins/fleet/storybook/context/cloud.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CloudSetup } from '../../../cloud/public'; + +export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => { + const cloud: CloudSetup = { + isCloudEnabled, + baseUrl: 'https://base.url', + cloudId: 'cloud-id', + cname: 'found.io', + deploymentUrl: 'https://deployment.url', + organizationUrl: 'https://organization.url', + profileUrl: 'https://profile.url', + snapshotsUrl: 'https://snapshots.url', + }; + + return cloud; +}; diff --git a/x-pack/plugins/fleet/storybook/context/doc_links.ts b/x-pack/plugins/fleet/storybook/context/doc_links.ts index 56287dd9116a9..bb6d8086d1cd8 100644 --- a/x-pack/plugins/fleet/storybook/context/doc_links.ts +++ b/x-pack/plugins/fleet/storybook/context/doc_links.ts @@ -10,9 +10,12 @@ import type { DocLinksStart } from 'kibana/public'; export const getDocLinks = () => { const docLinks: DocLinksStart = { links: { + elasticStackGetStarted: + 'https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-elastic-stack.html', fleet: { learnMoreBlog: 'https://www.elastic.co/blog/elastic-agent-and-fleet-make-it-easier-to-integrate-your-systems-with-elastic', + apiKeysLearnMore: 'https://www.elastic.co/guide/en/kibana/master/api-keys.html', }, }, } as unknown as DocLinksStart; diff --git a/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts b/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts index 2a6012272d4b8..dfe8e905be089 100644 --- a/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts +++ b/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts @@ -6,4527 +6,307 @@ */ import type { GetPackagesResponse } from '../../../public/types'; -import { ElasticsearchAssetType, KibanaSavedObjectType } from '../../../common/types'; export const response: GetPackagesResponse['response'] = [ { - name: 'apache', - title: 'Apache', - version: '0.8.1', - release: 'experimental', - description: 'Apache Integration', - type: 'integration', - download: '/epr/apache/apache-0.8.1.zip', - path: '/package/apache/0.8.1', - icons: [ - { - src: '/img/logo_apache.svg', - path: '/package/apache/0.8.1/img/logo_apache.svg', - title: 'Apache Logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'apache', - title: 'Apache logs and metrics', - description: 'Collect logs and metrics from Apache instances', - }, - ], - id: 'apache', - status: 'not_installed', - }, - { - name: 'apm', - title: 'Elastic APM', - version: '0.4.0', - release: 'beta', - description: 'Ingest APM data', - type: 'integration', - download: '/epr/apm/apm-0.4.0.zip', - path: '/package/apm/0.4.0', - icons: [ - { - src: '/img/logo_apm.svg', - path: '/package/apm/0.4.0/img/logo_apm.svg', - title: 'APM Logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'apmserver', - title: 'Elastic APM Integration', - description: 'Elastic APM Integration', - }, - ], - id: 'apm', - status: 'not_installed', - }, - { - name: 'auditd', - title: 'Auditd', - version: '1.2.0', - release: 'ga', - description: 'This Elastic integration collects and parses logs from the Audit daemon (auditd)', - type: 'integration', - download: '/epr/auditd/auditd-1.2.0.zip', - path: '/package/auditd/1.2.0', - icons: [ - { - src: '/img/linux.svg', - path: '/package/auditd/1.2.0/img/linux.svg', - title: 'linux', - size: '299x354', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'auditd', - title: 'Auditd logs', - description: 'Collect logs from Auditd instances', - }, - ], - id: 'auditd', - status: 'not_installed', - }, - { - name: 'aws', - title: 'AWS', - version: '0.10.7', - release: 'beta', - description: 'This integration collects logs and metrics from Amazon Web Services (AWS)', - type: 'integration', - download: '/epr/aws/aws-0.10.7.zip', - path: '/package/aws/0.10.7', - icons: [ - { - src: '/img/logo_aws.svg', - path: '/package/aws/0.10.7/img/logo_aws.svg', - title: 'logo aws', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'billing', - title: 'AWS Billing', - description: 'Collect AWS billing metrics', - icons: [ - { - src: '/img/logo_billing.svg', - path: '/package/aws/0.10.7/img/logo_billing.svg', - title: 'AWS Billing logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'cloudtrail', - title: 'AWS Cloudtrail', - description: 'Collect logs from AWS Cloudtrail', - icons: [ - { - src: '/img/logo_cloudtrail.svg', - path: '/package/aws/0.10.7/img/logo_cloudtrail.svg', - title: 'AWS Cloudtrail logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'cloudwatch', - title: 'AWS CloudWatch', - description: 'Collect logs and metrics from CloudWatch', - icons: [ - { - src: '/img/logo_cloudwatch.svg', - path: '/package/aws/0.10.7/img/logo_cloudwatch.svg', - title: 'AWS CloudWatch logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'dynamodb', - title: 'AWS DynamoDB', - description: 'Collect AWS DynamoDB metrics', - icons: [ - { - src: '/img/logo_dynamodb.svg', - path: '/package/aws/0.10.7/img/logo_dynamodb.svg', - title: 'AWS DynamoDB logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'ebs', - title: 'AWS EBS', - description: 'Collect AWS EBS metrics', - icons: [ - { - src: '/img/logo_ebs.svg', - path: '/package/aws/0.10.7/img/logo_ebs.svg', - title: 'AWS EBS logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'ec2', - title: 'AWS EC2', - description: 'Collect logs and metrics from EC2 service', - icons: [ - { - src: '/img/logo_ec2.svg', - path: '/package/aws/0.10.7/img/logo_ec2.svg', - title: 'AWS EC2 logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'elb', - title: 'AWS ELB', - description: 'Collect logs and metrics from ELB service', - icons: [ - { - src: '/img/logo_elb.svg', - path: '/package/aws/0.10.7/img/logo_elb.svg', - title: 'AWS ELB logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'lambda', - title: 'AWS Lambda', - description: 'Collect AWS Lambda metrics', - icons: [ - { - src: '/img/logo_lambda.svg', - path: '/package/aws/0.10.7/img/logo_lambda.svg', - title: 'AWS Lambda logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'natgateway', - title: 'AWS NATGateway', - description: 'Collect AWS NATGateway metrics', - icons: [ - { - src: '/img/logo_natgateway.svg', - path: '/package/aws/0.10.7/img/logo_natgateway.svg', - title: 'AWS NATGateway logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'rds', - title: 'AWS RDS', - description: 'Collect AWS RDS metrics', - icons: [ - { - src: '/img/logo_rds.svg', - path: '/package/aws/0.10.7/img/logo_rds.svg', - title: 'AWS RDS logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 's3', - title: 'AWS S3', - description: 'Collect AWS S3 metrics', - icons: [ - { - src: '/img/logo_s3.svg', - path: '/package/aws/0.10.7/img/logo_s3.svg', - title: 'AWS S3 logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'sns', - title: 'AWS SNS', - description: 'Collect AWS SNS metrics', - icons: [ - { - src: '/img/logo_sns.svg', - path: '/package/aws/0.10.7/img/logo_sns.svg', - title: 'AWS SNS logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'sqs', - title: 'AWS SQS', - description: 'Collect AWS SQS metrics', - icons: [ - { - src: '/img/logo_sqs.svg', - path: '/package/aws/0.10.7/img/logo_sqs.svg', - title: 'AWS SQS logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'transitgateway', - title: 'AWS Transit Gateway', - description: 'Collect AWS Transit Gateway metrics', - icons: [ - { - src: '/img/logo_transitgateway.svg', - path: '/package/aws/0.10.7/img/logo_transitgateway.svg', - title: 'AWS Transit Gateway logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'usage', - title: 'AWS Usage', - description: 'Collect AWS Usage metrics', - }, - { - name: 'vpcflow', - title: 'AWS VPC Flow', - description: 'Collect AWS vpcflow logs', - icons: [ - { - src: '/img/logo_vpcflow.svg', - path: '/package/aws/0.10.7/img/logo_vpcflow.svg', - title: 'AWS VPC logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'vpn', - title: 'AWS VPN', - description: 'Collect AWS VPN metrics', - icons: [ - { - src: '/img/logo_vpn.svg', - path: '/package/aws/0.10.7/img/logo_vpn.svg', - title: 'AWS VPN logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - ], - id: 'aws', - status: 'not_installed', - }, - { - name: 'azure', - title: 'Azure Logs', - version: '0.8.5', - release: 'beta', - description: 'This Elastic integration collects logs from Azure', - type: 'integration', - download: '/epr/azure/azure-0.8.5.zip', - path: '/package/azure/0.8.5', - icons: [ - { - src: '/img/azure_logs_logo.png', - path: '/package/azure/0.8.5/img/azure_logs_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'adlogs', - title: 'Azure Active Directory logs', - description: 'Azure Directory logs integration', - icons: [ - { - src: '/img/active_directory_logo.png', - path: '/package/azure/0.8.5/img/active_directory_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'platformlogs', - title: 'Azure platform logs', - description: 'Azure platform logs integration', - icons: [ - { - src: '/img/platformlogs_logo.png', - path: '/package/azure/0.8.5/img/platformlogs_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'activitylogs', - title: 'Azure activity logs', - description: 'Azure activity logs integration', - icons: [ - { - src: '/img/platformlogs_logo.png', - path: '/package/azure/0.8.5/img/platformlogs_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'springcloudlogs', - title: 'Azure Spring Cloud logs', - description: 'Azure Spring Cloud logs integration', - icons: [ - { - src: '/img/spring_logs.svg', - path: '/package/azure/0.8.5/img/spring_logs.svg', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - ], - id: 'azure', - status: 'not_installed', - }, - { - name: 'azure_application_insights', - title: 'Azure Application Insights Metrics Overview', - version: '0.1.0', - release: 'beta', - description: 'Azure Application Insights', - type: 'integration', - download: '/epr/azure_application_insights/azure_application_insights-0.1.0.zip', - path: '/package/azure_application_insights/0.1.0', - icons: [ - { - src: '/img/app_insights.png', - path: '/package/azure_application_insights/0.1.0/img/app_insights.png', - title: 'logo docker', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'app_insights', - title: 'Azure Application Insights metrics', - description: 'Azure Application Insights Metrics Integration', - icons: [ - { - src: '/img//app_insights.png', - path: '/package/azure_application_insights/0.1.0/img/app_insights.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'app_state', - title: 'Azure Application State Insights metrics', - description: 'Azure Application State Insights Metrics Integration', - icons: [ - { - src: '/img/application_insights_blue.png', - path: '/package/azure_application_insights/0.1.0/img/application_insights_blue.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - ], - id: 'azure_application_insights', - status: 'not_installed', - }, - { - name: 'azure_metrics', - title: 'Azure resource metrics', - version: '0.3.2', - release: 'beta', - description: 'This Elastic integration collects and aggregates metrics from Azure resources', - type: 'integration', - download: '/epr/azure_metrics/azure_metrics-0.3.2.zip', - path: '/package/azure_metrics/0.3.2', - icons: [ - { - src: '/img/azure_metrics_logo.png', - path: '/package/azure_metrics/0.3.2/img/azure_metrics_logo.png', - title: 'logo docker', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'monitor', - title: 'Azure Monitor metrics', - description: 'Azure Monitor Metrics Integration', - icons: [ - { - src: '/img/monitor_logo.png', - path: '/package/azure_metrics/0.3.2/img/monitor_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'compute_vm', - title: 'Azure Virtual Machines metrics', - description: 'Azure Virtual Machines Metrics Integration', - icons: [ - { - src: '/img/compute_vm_logo.png', - path: '/package/azure_metrics/0.3.2/img/compute_vm_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'compute_vm_scaleset', - title: 'Azure Virtual Machines Scaleset metrics', - description: 'Azure Virtual Machines Scaleset Metrics Integration', - icons: [ - { - src: '/img/compute_vm_scaleset_logo.png', - path: '/package/azure_metrics/0.3.2/img/compute_vm_scaleset_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'container_registry', - title: 'Azure Container Registry metrics', - description: 'Azure Container Registry Metrics Integration', - icons: [ - { - src: '/img/container_registry_logo.png', - path: '/package/azure_metrics/0.3.2/img/container_registry_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'container_instance', - title: 'Azure Container Instance metrics', - description: 'Azure Container Instance Metrics Integration', - icons: [ - { - src: '/img/container_instance_logo.png', - path: '/package/azure_metrics/0.3.2/img/container_instance_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'container_service', - title: 'Azure Container Service metrics', - description: 'Azure Container Service Metrics Integration', - icons: [ - { - src: '/img/container_service_logo.png', - path: '/package/azure_metrics/0.3.2/img/container_service_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'database_account', - title: 'Azure Database Account metrics', - description: 'Azure Database Account Metrics Integration', - icons: [ - { - src: '/img/database_account_logo.png', - path: '/package/azure_metrics/0.3.2/img/database_account_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'storage_account', - title: 'Azure Storage Account metrics', - description: 'Azure Storage Account Metrics Integration', - icons: [ - { - src: '/img/storage_account_logo.png', - path: '/package/azure_metrics/0.3.2/img/storage_account_logo.png', - title: 'logo azure', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - ], - id: 'azure_metrics', - status: 'not_installed', - }, - { - name: 'barracuda', - title: 'Barracuda', - version: '0.4.0', - release: 'experimental', - description: 'Barracuda Integration', - type: 'integration', - download: '/epr/barracuda/barracuda-0.4.0.zip', - path: '/package/barracuda/0.4.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/barracuda/0.4.0/img/logo.svg', - title: 'Barracuda logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'barracuda', - title: 'Barracuda logs', - description: 'Collect Barracuda logs from syslog or a file.', - }, - ], - id: 'barracuda', - status: 'not_installed', - }, - { - name: 'bluecoat', - title: 'Blue Coat Director', - version: '0.3.0', - release: 'experimental', - description: 'Blue Coat Director Integration', - type: 'integration', - download: '/epr/bluecoat/bluecoat-0.3.0.zip', - path: '/package/bluecoat/0.3.0', - policy_templates: [ - { - name: 'director', - title: 'Blue Coat Director', - description: 'Collect Blue Coat Director logs from syslog or a file.', - }, - ], - id: 'bluecoat', - status: 'not_installed', - }, - { - name: 'carbonblack_edr', - title: 'VMware Carbon Black EDR', - version: '0.2.0', - release: 'experimental', - description: 'Carbon Black EDR Integration', - type: 'integration', - download: '/epr/carbonblack_edr/carbonblack_edr-0.2.0.zip', - path: '/package/carbonblack_edr/0.2.0', - policy_templates: [ - { - name: 'log', - title: 'Carbon Black EDR logs', - description: 'Collect logs from Carbon Black EDR', - }, - ], - id: 'carbonblack_edr', - status: 'not_installed', - }, - { - name: 'cef', - title: 'CEF', - version: '0.5.2', - release: 'experimental', - description: 'This Elastic integration collects logs in common event format (CEF)', - type: 'integration', - download: '/epr/cef/cef-0.5.2.zip', - path: '/package/cef/0.5.2', - policy_templates: [ - { - name: 'cef', - title: 'CEF logs', - description: 'Collect logs from CEF instances', - }, - ], - id: 'cef', - status: 'not_installed', - }, - { - name: 'checkpoint', - title: 'Check Point', - version: '0.8.2', - release: 'experimental', - description: 'This Elastic integration collects logs from Check Point products', - type: 'integration', - download: '/epr/checkpoint/checkpoint-0.8.2.zip', - path: '/package/checkpoint/0.8.2', - icons: [ - { - src: '/img/checkpoint-logo.svg', - path: '/package/checkpoint/0.8.2/img/checkpoint-logo.svg', - title: 'Check Point', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'checkpoint', - title: 'Check Point logs', - description: 'Collect logs from Check Point instances', - }, - ], - id: 'checkpoint', - status: 'not_installed', - }, - { - name: 'cisco', - title: 'Cisco', - version: '0.10.0', - release: 'experimental', - description: 'Cisco Integration', - type: 'integration', - download: '/epr/cisco/cisco-0.10.0.zip', - path: '/package/cisco/0.10.0', - icons: [ - { - src: '/img/cisco.svg', - path: '/package/cisco/0.10.0/img/cisco.svg', - title: 'cisco', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'cisco', - title: 'Cisco logs', - description: 'Collect logs from Cisco instances', - }, - ], - id: 'cisco', - status: 'not_installed', - }, - { - name: 'crowdstrike', - title: 'CrowdStrike', - version: '0.6.0', - release: 'experimental', - description: 'CrowdStrike Integration', - type: 'integration', - download: '/epr/crowdstrike/crowdstrike-0.6.0.zip', - path: '/package/crowdstrike/0.6.0', - icons: [ - { - src: '/img/logo-integrations-crowdstrike.svg', - path: '/package/crowdstrike/0.6.0/img/logo-integrations-crowdstrike.svg', - title: 'CrowdStrike', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'crowdstrike', - title: 'CrowdStrike Falcon logs', - description: 'Collect logs from CrowdStrike Falcon', - }, - ], - id: 'crowdstrike', - status: 'not_installed', - }, - { - name: 'cyberark', - title: 'Cyber-Ark - Deprecated', - version: '0.3.0', - release: 'experimental', - description: - "Cyber-Ark Integration - Deprecated: Use 'CyberArk Privileged Access Security' instead.", - type: 'integration', - download: '/epr/cyberark/cyberark-0.3.0.zip', - path: '/package/cyberark/0.3.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/cyberark/0.3.0/img/logo.svg', - title: 'CyberArk logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'cyberark', - title: 'CyberArk logs', - description: 'Collect CyberArk logs from syslog or a file.', - }, - ], - id: 'cyberark', - status: 'not_installed', - }, - { - name: 'cyberarkpas', - title: 'CyberArk Privileged Access Security', - version: '1.2.3', - release: 'beta', - description: 'This Elastic integration collects logs from CyberArk', - type: 'integration', - download: '/epr/cyberarkpas/cyberarkpas-1.2.3.zip', - path: '/package/cyberarkpas/1.2.3', - icons: [ - { - src: '/img/logo.svg', - path: '/package/cyberarkpas/1.2.3/img/logo.svg', - title: 'CyberArk logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'cyberarkpas', - title: 'CyberArk Privileged Access Security audit logs', - description: 'Collect logs from Vault instances', - }, - ], - id: 'cyberarkpas', - status: 'not_installed', - }, - { - name: 'cylance', - title: 'CylanceProtect', - version: '0.3.0', - release: 'experimental', - description: 'CylanceProtect Integration', - type: 'integration', - download: '/epr/cylance/cylance-0.3.0.zip', - path: '/package/cylance/0.3.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/cylance/0.3.0/img/logo.svg', - title: 'CylanceProtect logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'protect', - title: 'CylanceProtect', - description: 'Collect CylanceProtect logs from syslog or a file.', - }, - ], - id: 'cylance', - status: 'not_installed', - }, - { - name: 'elastic_agent', - title: 'Elastic Agent', - version: '1.0.0', - release: 'ga', - description: 'This Elastic integration collects metrics from Elastic Agent', - type: 'integration', - download: '/epr/elastic_agent/elastic_agent-1.0.0.zip', - path: '/package/elastic_agent/1.0.0', - icons: [ - { - src: '/img/logo_elastic_agent.svg', - path: '/package/elastic_agent/1.0.0/img/logo_elastic_agent.svg', - title: 'logo Elastic Agent', - size: '64x64', - type: 'image/svg+xml', - }, - ], - id: 'elastic_agent', - status: 'installed', - savedObject: { - type: 'epm-packages', - id: 'elastic_agent', - attributes: { - installed_kibana: [ - { - id: 'elastic_agent-f47f18cc-9c7d-4278-b2ea-a6dee816d395', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'elastic_agent-47d87552-8421-4cfc-bc5d-4a7205f5b007', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'elastic_agent-93a8a11d-b2da-4ef3-81dc-c7040560ffde', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'elastic_agent-a11c250a-865f-4eb2-9441-882d229313be', - type: KibanaSavedObjectType.visualization, - }, - ], - installed_es: [ - { - id: 'metrics-elastic_agent.elastic_agent', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-elastic_agent.elastic_agent@mappings', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-elastic_agent.elastic_agent@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - ], - package_assets: [ - { - id: '0100ed87-1b21-5959-9ee3-6f6fe60b0126', - type: 'epm-packages-assets', - }, - { - id: '79617489-e64c-5867-aa21-131d3f76d7c0', - type: 'epm-packages-assets', - }, - { - id: 'c1da5c89-8489-5a28-b7d8-d71f3680193e', - type: 'epm-packages-assets', - }, - { - id: 'e2ebdefd-4511-57c6-81bd-9b206d5de396', - type: 'epm-packages-assets', - }, - { - id: 'aae8cab7-af27-5e71-9a95-a76e20ccfd0f', - type: 'epm-packages-assets', - }, - { - id: '14935ecd-d51c-59c8-8c2b-fc0a3c94c3bc', - type: 'epm-packages-assets', - }, - { - id: '0173d8b8-3625-5a87-9ff9-b6885d475e58', - type: 'epm-packages-assets', - }, - { - id: '2c518c0e-44b7-5121-9cbe-b9794317fc65', - type: 'epm-packages-assets', - }, - { - id: 'c5d0bc02-78bc-558f-a26e-406aeaeb0a6b', - type: 'epm-packages-assets', - }, - { - id: '38e9b2ce-4833-594b-95e6-d4dc663ecd6a', - type: 'epm-packages-assets', - }, - { - id: '12996859-f0e4-51f5-b842-a34781b11164', - type: 'epm-packages-assets', - }, - { - id: '70b80a43-df71-5e8c-887d-c09114998a72', - type: 'epm-packages-assets', - }, - { - id: 'bd50d62b-1f81-56ce-accf-82fe25f2723e', - type: 'epm-packages-assets', - }, - ], - es_index_patterns: { - elastic_agent: 'metrics-elastic_agent.elastic_agent-*', - }, - name: 'elastic_agent', - version: '1.0.0', - internal: false, - removable: false, - install_version: '1.0.0', - install_status: 'installed', - install_started_at: '2021-08-25T19:44:41.090Z', - install_source: 'registry', - keep_policies_up_to_date: false, - }, - references: [], - coreMigrationVersion: '7.14.0', - updated_at: '2021-08-25T19:45:01.491Z', - version: 'Wzc3NjQsNF0=', - // score: 0, TODO: this is not represented in any type, but is returned by the API, - }, - }, - { - name: 'endpoint', - title: 'Endpoint Security', - version: '1.0.0', - release: 'ga', - description: - 'Protect your hosts with threat prevention, detection, and deep security data visibility.', - type: 'integration', - download: '/epr/endpoint/endpoint-1.0.0.zip', - path: '/package/endpoint/1.0.0', - icons: [ - { - src: '/img/security-logo-color-64px.svg', - path: '/package/endpoint/1.0.0/img/security-logo-color-64px.svg', - size: '16x16', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'endpoint', - title: 'Endpoint Security Integration', - description: 'Interact with the endpoint.', - }, - ], - id: 'endpoint', - status: 'not_installed', - }, - { - name: 'f5', - title: 'F5', - version: '0.4.0', - release: 'experimental', - description: 'F5 Integration', - type: 'integration', - download: '/epr/f5/f5-0.4.0.zip', - path: '/package/f5/0.4.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/f5/0.4.0/img/logo.svg', - title: 'Big-IP Access Policy Manager logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'F5', - title: 'F5 logs', - description: 'Collect F5 logs from syslog or a file.', - }, - ], - id: 'f5', - status: 'not_installed', - }, - { - name: 'fleet_server', - title: 'Fleet Server', - version: '1.0.1', - release: 'ga', - description: 'Centrally manage Elastic Agents with the Fleet Server integration', - type: 'integration', - download: '/epr/fleet_server/fleet_server-1.0.1.zip', - path: '/package/fleet_server/1.0.1', - icons: [ - { - src: '/img/logo_fleet_server.svg', - path: '/package/fleet_server/1.0.1/img/logo_fleet_server.svg', - title: 'logo Fleet Server', - size: '64x64', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'fleet_server', - title: 'Fleet Server', - description: 'Fleet Server setup', - }, - ], - id: 'fleet_server', - status: 'installed', - savedObject: { - type: 'epm-packages', - id: 'fleet_server', - attributes: { - installed_kibana: [], - installed_es: [], - package_assets: [ - { - id: '4a805c49-0059-52f4-bdc0-56388a9708a7', - type: 'epm-packages-assets', - }, - { - id: '738689f4-0777-5219-ac20-5517c593f6f6', - type: 'epm-packages-assets', - }, - { - id: '1e5f0249-d9a4-5259-8905-e830165185da', - type: 'epm-packages-assets', - }, - { - id: '67e878de-de6e-5123-ad62-caff2e59ef9b', - type: 'epm-packages-assets', - }, - { - id: 'fa44229e-987c-58d5-bef9-95dbaedbe2d8', - type: 'epm-packages-assets', - }, - ], - es_index_patterns: {}, - name: 'fleet_server', - version: '1.0.1', - internal: false, - removable: false, - install_version: '1.0.1', - install_status: 'installed', - install_started_at: '2021-08-25T19:44:37.078Z', - install_source: 'registry', - keep_policies_up_to_date: false, - }, - references: [], - coreMigrationVersion: '7.14.0', - updated_at: '2021-08-25T19:44:53.517Z', - version: 'WzczMTIsNF0=', - // score: 0, TODO: this is not represented in any type, but is returned by the API, - }, - }, - { - name: 'fortinet', - title: 'Fortinet', - version: '1.1.2', - release: 'ga', - description: 'This Elastic integration collects logs from Fortinet instances', - type: 'integration', - download: '/epr/fortinet/fortinet-1.1.2.zip', - path: '/package/fortinet/1.1.2', - icons: [ - { - src: '/img/fortinet-logo.svg', - path: '/package/fortinet/1.1.2/img/fortinet-logo.svg', - title: 'Fortinet', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'fortinet', - title: 'Fortinet logs', - description: 'Collect logs from Fortinet instances', - }, - ], - id: 'fortinet', - status: 'not_installed', - }, - { - name: 'gcp', - title: 'Google Cloud Platform (GCP)', - version: '0.2.0', - release: 'experimental', - description: 'Google Cloud Platform (GCP) Integration', - type: 'integration', - download: '/epr/gcp/gcp-0.2.0.zip', - path: '/package/gcp/0.2.0', - icons: [ - { - src: '/img/logo_gcp.svg', - path: '/package/gcp/0.2.0/img/logo_gcp.svg', - title: 'logo gcp', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'gcp', - title: 'Google Cloud Platform (GCP) logs', - description: 'Collect logs from Google Cloud Platform (GCP) instances', - }, - ], - id: 'gcp', - status: 'not_installed', - }, - { - name: 'google_workspace', - title: 'Google Workspace', - version: '0.7.3', - release: 'experimental', - description: 'This Elastic integration collects logs from Google Workspace APIs', - type: 'integration', - download: '/epr/google_workspace/google_workspace-0.7.3.zip', - path: '/package/google_workspace/0.7.3', - icons: [ - { - src: '/img/logo.svg', - path: '/package/google_workspace/0.7.3/img/logo.svg', - title: 'logo Google', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'google_workspace', - title: 'Google Workspace logs', - description: 'Collect logs from Google Workspace APIs', - }, - ], - id: 'google_workspace', - status: 'not_installed', - }, - { - name: 'haproxy', - title: 'HAProxy', - version: '0.4.0', - release: 'experimental', - description: 'HAProxy Integration', - type: 'integration', - download: '/epr/haproxy/haproxy-0.4.0.zip', - path: '/package/haproxy/0.4.0', - icons: [ - { - src: '/img/logo_haproxy.svg', - path: '/package/haproxy/0.4.0/img/logo_haproxy.svg', - title: 'logo HAProxy', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'haproxy', - title: 'HAProxy logs and metrics', - description: 'Collect logs and metrics from HAProxy instances', - }, - ], - id: 'haproxy', - status: 'not_installed', - }, - { - name: 'iis', - title: 'IIS', - version: '0.5.0', - release: 'beta', - description: 'IIS Integration', - type: 'integration', - download: '/epr/iis/iis-0.5.0.zip', - path: '/package/iis/0.5.0', - icons: [ - { - src: '/img/iis.svg', - path: '/package/iis/0.5.0/img/iis.svg', - title: 'iis', - size: '100x100', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'iis', - title: 'IIS logs and metrics', - description: 'Collect logs and metrics from IIS instances', - }, - ], - id: 'iis', - status: 'not_installed', - }, - { - name: 'imperva', - title: 'Imperva SecureSphere', - version: '0.3.0', - release: 'experimental', - description: 'Imperva SecureSphere Integration', - type: 'integration', - download: '/epr/imperva/imperva-0.3.0.zip', - path: '/package/imperva/0.3.0', - policy_templates: [ - { - name: 'securesphere', - title: 'Imperva SecureSphere', - description: 'Collect Imperva SecureSphere logs from syslog or a file.', - }, - ], - id: 'imperva', - status: 'not_installed', - }, - { - name: 'infoblox', - title: 'Infoblox NIOS', - version: '0.3.0', - release: 'experimental', - description: 'Infoblox NIOS Integration', - type: 'integration', - download: '/epr/infoblox/infoblox-0.3.0.zip', - path: '/package/infoblox/0.3.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/infoblox/0.3.0/img/logo.svg', - title: 'Infoblox NIOS logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'nios', - title: 'Infoblox NIOS', - description: 'Collect Infoblox NIOS logs from syslog or a file.', - }, - ], - id: 'infoblox', - status: 'not_installed', - }, - { - name: 'iptables', - title: 'Iptables', - version: '0.5.0', - release: 'experimental', - description: 'This Elastic integration collects logs from Iptables instances', - type: 'integration', - download: '/epr/iptables/iptables-0.5.0.zip', - path: '/package/iptables/0.5.0', - icons: [ - { - src: '/img/linux.svg', - path: '/package/iptables/0.5.0/img/linux.svg', - title: 'linux', - size: '299x354', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'iptables', - title: 'Iptables logs', - description: 'Collect logs from iptables instances', - }, - ], - id: 'iptables', - status: 'not_installed', - }, - { - name: 'juniper', - title: 'Juniper', - version: '0.7.0', - release: 'experimental', - description: 'Juniper Integration', - type: 'integration', - download: '/epr/juniper/juniper-0.7.0.zip', - path: '/package/juniper/0.7.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/juniper/0.7.0/img/logo.svg', - title: 'Juniper logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'juniper', - title: 'Juniper logs', - description: 'Collect Juniper logs from syslog or a file.', - }, - ], - id: 'juniper', - status: 'not_installed', - }, - { - name: 'kafka', - title: 'Kafka', - version: '0.5.0', - release: 'experimental', - description: 'Kafka Integration', - type: 'integration', - download: '/epr/kafka/kafka-0.5.0.zip', - path: '/package/kafka/0.5.0', - icons: [ - { - src: '/img/logo_kafka.svg', - path: '/package/kafka/0.5.0/img/logo_kafka.svg', - title: 'logo kafka', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'kafka', - title: 'Kafka logs and metrics', - description: 'Collect logs and metrics from Kafka brokers', - }, - ], - id: 'kafka', - status: 'not_installed', - }, - { - name: 'kubernetes', - title: 'Kubernetes', - version: '0.8.0', - release: 'experimental', - description: 'Kubernetes Integration', - type: 'integration', - download: '/epr/kubernetes/kubernetes-0.8.0.zip', - path: '/package/kubernetes/0.8.0', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'kubelet', - title: 'Kubelet', - description: 'Collect metrics from Kubernetes Kubelet API', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'kube-state-metrics', - title: 'kube-state-metrics', - description: 'Collect metrics from kube-state-metrics', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'kube-apiserver', - title: 'kube-apiserver', - description: 'Collect metrics from Kubernetes API Server', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'kube-proxy', - title: 'kube-proxy', - description: 'Collect metrics from Kubernetes Proxy', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'kube-scheduler', - title: 'kube-scheduler', - description: 'Collect metrics from Kubernetes Scheduler', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'kube-controller-manager', - title: 'kube-controller-manager', - description: 'Collect metrics from Kubernetes controller-manager', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - { - name: 'events', - title: 'Events', - description: 'Collect events from Kubernetes API server', - icons: [ - { - src: '/img/logo_kubernetes.svg', - path: '/package/kubernetes/0.8.0/img/logo_kubernetes.svg', - title: 'Logo Kubernetes', - size: '32x32', - type: 'image/svg+xml', - }, - ], - }, - ], - id: 'kubernetes', - status: 'not_installed', - }, - { - name: 'linux', - title: 'Linux', - version: '0.4.1', - release: 'beta', - description: 'Linux Integration', - type: 'integration', - download: '/epr/linux/linux-0.4.1.zip', - path: '/package/linux/0.4.1', - policy_templates: [ - { - name: 'system', - title: 'Linux kernel metrics', - description: 'Collect system metrics from Linux operating systems', - }, - ], - id: 'linux', - status: 'not_installed', - }, - { - name: 'log', - title: 'Custom logs', - version: '0.4.6', - release: 'experimental', - description: 'Collect your custom logs.\n', - type: 'integration', - download: '/epr/log/log-0.4.6.zip', - path: '/package/log/0.4.6', - icons: [ - { - src: '/img/icon.svg', - path: '/package/log/0.4.6/img/icon.svg', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'logs', - title: 'Custom logs', - description: 'Collect your custom log files.', - }, - ], - id: 'log', - status: 'not_installed', - }, - { - name: 'microsoft', - title: 'Microsoft', - version: '0.6.0', - release: 'experimental', - description: 'Microsoft Integration', - type: 'integration', - download: '/epr/microsoft/microsoft-0.6.0.zip', - path: '/package/microsoft/0.6.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/microsoft/0.6.0/img/logo.svg', - title: 'Microsoft logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'microsoft', - title: 'Microsoft', - description: 'Collect logs from Microsoft products', - }, - ], - id: 'microsoft', - status: 'not_installed', - }, - { - name: 'mongodb', - title: 'MongoDB', - version: '0.6.0', - release: 'experimental', - description: 'MongoDB Integration', - type: 'integration', - download: '/epr/mongodb/mongodb-0.6.0.zip', - path: '/package/mongodb/0.6.0', - icons: [ - { - src: '/img/logo_mongodb.svg', - path: '/package/mongodb/0.6.0/img/logo_mongodb.svg', - title: 'logo mongodb', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'mongodb', - title: 'MongoDB logs and metrics', - description: 'Collect logs and metrics from MongoDB instances', - }, - ], - id: 'mongodb', - status: 'not_installed', - }, - { - name: 'mysql', - title: 'MySQL', - version: '0.5.0', - release: 'beta', - description: 'MySQL Integration', - type: 'integration', - download: '/epr/mysql/mysql-0.5.0.zip', - path: '/package/mysql/0.5.0', - icons: [ - { - src: '/img/logo_mysql.svg', - path: '/package/mysql/0.5.0/img/logo_mysql.svg', - title: 'logo mysql', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'mysql', - title: 'MySQL logs and metrics', - description: 'Collect logs and metrics from MySQL instances', - }, - ], - id: 'mysql', - status: 'not_installed', - }, - { - name: 'nats', - title: 'NATS', - version: '0.4.0', - release: 'experimental', - description: 'NATS Integration', - type: 'integration', - download: '/epr/nats/nats-0.4.0.zip', - path: '/package/nats/0.4.0', - icons: [ - { - src: '/img/nats.svg', - path: '/package/nats/0.4.0/img/nats.svg', - title: 'NATS Logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'nats', - title: 'NATS Logs and Metrics', - description: 'Collect logs and metrics from NATS instances', - }, - ], - id: 'nats', - status: 'not_installed', - }, - { - name: 'netflow', - title: 'NetFlow', - version: '1.2.0', - release: 'ga', - description: 'This Elastic integration collects logs from NetFlow', - type: 'integration', - download: '/epr/netflow/netflow-1.2.0.zip', - path: '/package/netflow/1.2.0', - policy_templates: [ - { - name: 'netflow', - title: 'NetFlow logs', - description: 'Collect Netflow logs from networks via UDP', - }, - ], - id: 'netflow', - status: 'not_installed', - }, - { - name: 'netscout', - title: 'Arbor Peakflow SP', - version: '0.3.0', - release: 'experimental', - description: 'Arbor Peakflow SP Integration', - type: 'integration', - download: '/epr/netscout/netscout-0.3.0.zip', - path: '/package/netscout/0.3.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/netscout/0.3.0/img/logo.svg', - title: 'Arbor Peakflow SP logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'sightline', - title: 'Arbor Peakflow SP', - description: 'Collect Arbor Peakflow SP logs from syslog or a file.', - }, - ], - id: 'netscout', - status: 'not_installed', - }, - { - name: 'nginx', - title: 'Nginx', - version: '0.7.0', - release: 'experimental', - description: 'Nginx Integration', - type: 'integration', - download: '/epr/nginx/nginx-0.7.0.zip', - path: '/package/nginx/0.7.0', - icons: [ - { - src: '/img/logo_nginx.svg', - path: '/package/nginx/0.7.0/img/logo_nginx.svg', - title: 'logo nginx', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'nginx', - title: 'Nginx logs and metrics', - description: 'Collect logs and metrics from Nginx instances', - }, - ], - id: 'nginx', - status: 'not_installed', - }, - { - name: 'nginx_ingress_controller', - title: 'Nginx Ingress Controller', - version: '0.2.0', - release: 'experimental', - description: 'Nginx Ingress Controller Integration', - type: 'integration', - download: '/epr/nginx_ingress_controller/nginx_ingress_controller-0.2.0.zip', - path: '/package/nginx_ingress_controller/0.2.0', - icons: [ - { - src: '/img/logo_nginx.svg', - path: '/package/nginx_ingress_controller/0.2.0/img/logo_nginx.svg', - title: 'Nginx logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'nginx_ingress_controller', - title: 'Nginx Ingress Controller logs', - description: 'Collect logs from Nginx Ingress Controller instances', - }, - ], - id: 'nginx_ingress_controller', - status: 'not_installed', - }, - { - name: 'o365', - title: 'Office 365', - version: '1.1.4', - release: 'ga', - description: 'This Elastic integration collects events from Microsoft Office 365', - type: 'integration', - download: '/epr/o365/o365-1.1.4.zip', - path: '/package/o365/1.1.4', - icons: [ - { - src: '/img/logo-integrations-microsoft-365.svg', - path: '/package/o365/1.1.4/img/logo-integrations-microsoft-365.svg', - title: 'Microsoft Office 365', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'o365', - title: 'Office 365 logs', - description: 'Collect logs from Office 365', - }, - ], - id: 'o365', - status: 'not_installed', - }, - { - name: 'okta', - title: 'Okta', - version: '1.2.0', - release: 'ga', - description: 'This Elastic integration collects events from Okta', - type: 'integration', - download: '/epr/okta/okta-1.2.0.zip', - path: '/package/okta/1.2.0', - icons: [ - { - src: '/img/okta-logo.svg', - path: '/package/okta/1.2.0/img/okta-logo.svg', - title: 'Okta', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'okta', - title: 'Okta logs', - description: 'Collect logs from Okta', - }, - ], - id: 'okta', - status: 'not_installed', - }, - { - name: 'osquery', - title: 'Osquery Log Collection', - version: '0.6.0', - release: 'experimental', - description: 'This Elastic integration collects logs from Osquery instances', - type: 'integration', - download: '/epr/osquery/osquery-0.6.0.zip', - path: '/package/osquery/0.6.0', - icons: [ - { - src: '/img/logo_osquery.svg', - path: '/package/osquery/0.6.0/img/logo_osquery.svg', - title: 'logo osquery', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'osquery', - title: 'Osquery logs', - description: 'Collect logs from Osquery instances', - }, - ], - id: 'osquery', - status: 'not_installed', - }, - { - name: 'osquery_manager', - title: 'Osquery Manager', - version: '0.3.2', - release: 'beta', - description: - 'Centrally manage osquery deployments, run live queries, and schedule recurring queries', - type: 'integration', - download: '/epr/osquery_manager/osquery_manager-0.3.2.zip', - path: '/package/osquery_manager/0.3.2', - icons: [ - { - src: '/img/logo_osquery.svg', - path: '/package/osquery_manager/0.3.2/img/logo_osquery.svg', - title: 'logo osquery', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'osquery_manager', - title: 'Osquery Manager', - description: - 'Send interactive or scheduled queries to the osquery instances executed by the elastic-agent.', - }, - ], - id: 'osquery_manager', - status: 'not_installed', - }, - { - name: 'panw', - title: 'Palo Alto Networks', - version: '1.1.3', - release: 'ga', - description: 'Palo Alto Networks Integration', - type: 'integration', - download: '/epr/panw/panw-1.1.3.zip', - path: '/package/panw/1.1.3', - icons: [ - { - src: '/img/logo-integrations-paloalto-networks.svg', - path: '/package/panw/1.1.3/img/logo-integrations-paloalto-networks.svg', - title: 'Palo Alto Networks', - size: '216x216', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'panw', - title: 'Palo Alto Networks PAN-OS firewall logs', - description: 'Collect logs from Palo Alto Networks PAN-OS firewall', - }, - ], - id: 'panw', - status: 'not_installed', - }, - { - name: 'postgresql', - title: 'PostgreSQL', - version: '0.5.0', - release: 'experimental', - description: 'PostgreSQL Integration', - type: 'integration', - download: '/epr/postgresql/postgresql-0.5.0.zip', - path: '/package/postgresql/0.5.0', - icons: [ - { - src: '/img/logo_postgres.svg', - path: '/package/postgresql/0.5.0/img/logo_postgres.svg', - title: 'logo postgres', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'postgresql', - title: 'PostgreSQL logs and metrics', - description: 'Collect logs and metrics from PostgreSQL instances', - }, - ], - id: 'postgresql', - status: 'not_installed', - }, - { - name: 'prometheus', - title: 'Prometheus', - version: '0.4.1', - release: 'experimental', - description: 'Prometheus Integration', - type: 'integration', - download: '/epr/prometheus/prometheus-0.4.1.zip', - path: '/package/prometheus/0.4.1', - icons: [ - { - src: '/img/logo_prometheus.svg', - path: '/package/prometheus/0.4.1/img/logo_prometheus.svg', - title: 'logo prometheus', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'prometheus', - title: 'Prometheus metrics', - description: 'Collect metrics from Prometheus instances', - }, - ], - id: 'prometheus', - status: 'not_installed', - }, - { - name: 'proofpoint', - title: 'Proofpoint Email Security', - version: '0.2.0', - release: 'experimental', - description: 'Proofpoint Email Security Integration', - type: 'integration', - download: '/epr/proofpoint/proofpoint-0.2.0.zip', - path: '/package/proofpoint/0.2.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/proofpoint/0.2.0/img/logo.svg', - title: 'Proofpoint Email Security logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'proofpoint', - title: 'Proofpoint logs', - description: 'Collect Proofpoint logs from syslog or a file.', - }, - ], - id: 'proofpoint', - status: 'not_installed', - }, - { - name: 'rabbitmq', - title: 'RabbitMQ', - version: '0.4.1', - release: 'experimental', - description: 'RabbitMQ Integration', - type: 'integration', - download: '/epr/rabbitmq/rabbitmq-0.4.1.zip', - path: '/package/rabbitmq/0.4.1', - icons: [ - { - src: '/img/logo_rabbitmq.svg', - path: '/package/rabbitmq/0.4.1/img/logo_rabbitmq.svg', - title: 'RabbitMQ Logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'rabbitmq', - title: 'RabbitMQ logs and metrics', - description: 'Collect logs and metrics from RabbitMQ instances', - }, - ], - id: 'rabbitmq', - status: 'not_installed', - }, - { - name: 'radware', - title: 'Radware DefensePro', - version: '0.4.0', - release: 'experimental', - description: 'This Elastic integration collects logs from Radware DefensePro', - type: 'integration', - download: '/epr/radware/radware-0.4.0.zip', - path: '/package/radware/0.4.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/radware/0.4.0/img/logo.svg', - title: 'Radware DefensePro logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'defensepro', - title: 'Radware DefensePro', - description: 'Collect Radware DefensePro logs from syslog or a file.', - }, - ], - id: 'radware', - status: 'not_installed', - }, - { - name: 'redis', - title: 'Redis', - version: '0.5.0', - release: 'experimental', - description: 'Redis Integration', - type: 'integration', - download: '/epr/redis/redis-0.5.0.zip', - path: '/package/redis/0.5.0', - icons: [ - { - src: '/img/logo_redis.svg', - path: '/package/redis/0.5.0/img/logo_redis.svg', - title: 'logo redis', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'redis', - title: 'Redis logs and metrics', - description: 'Collect logs and metrics from Redis instances', - }, - ], - id: 'redis', - status: 'not_installed', - }, - { - name: 'santa', - title: 'Google Santa', - version: '0.4.0', - release: 'experimental', - description: 'This Elastic integration collects logs from Google Santa instances', - type: 'integration', - download: '/epr/santa/santa-0.4.0.zip', - path: '/package/santa/0.4.0', - icons: [ - { - src: '/img/icon.svg', - path: '/package/santa/0.4.0/img/icon.svg', - title: 'Google Santa', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'santa', - title: 'Google Santa logs', - description: 'Collect logs from Google Santa instances', - }, - ], - id: 'santa', - status: 'not_installed', - }, - { - name: 'security_detection_engine', - title: 'Prebuilt Security Detection Rules', - version: '0.14.1', + name: 'ga_not_installed', + title: 'a. GA, Not Installed', + version: '0.0.1', release: 'ga', - description: 'Prebuilt detection rules for Elastic Security', - type: 'integration', - download: '/epr/security_detection_engine/security_detection_engine-0.14.1.zip', - path: '/package/security_detection_engine/0.14.1', - icons: [ - { - src: '/img/security-logo-color-64px.svg', - path: '/package/security_detection_engine/0.14.1/img/security-logo-color-64px.svg', - size: '16x16', - type: 'image/svg+xml', - }, - ], - id: 'security_detection_engine', - status: 'not_installed', - }, - { - name: 'sonicwall', - title: 'Sonicwall-FW', - version: '0.3.0', - release: 'experimental', - description: 'Sonicwall-FW Integration', - type: 'integration', - download: '/epr/sonicwall/sonicwall-0.3.0.zip', - path: '/package/sonicwall/0.3.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/sonicwall/0.3.0/img/logo.svg', - title: 'Sonicwall-FW logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'firewall', - title: 'Sonicwall-FW', - description: 'Collect Sonicwall-FW logs from syslog or a file.', - }, - ], - id: 'sonicwall', - status: 'not_installed', - }, - { - name: 'sophos', - title: 'Sophos', - version: '0.4.0', - release: 'experimental', - description: 'Sophos Integration', + description: 'A package that is GA, but not installed', type: 'integration', - download: '/epr/sophos/sophos-0.4.0.zip', - path: '/package/sophos/0.4.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/sophos/0.4.0/img/logo.svg', - title: 'Sophos logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'sophos', - title: 'Sophos logs', - description: 'Collect Sophos logs from syslog or a file.', - }, - ], - id: 'sophos', + download: '/epr/ga/not_installed', + path: '/package/ga/not_installed', + id: 'ga_not_installed', status: 'not_installed', + categories: ['aws', 'azure'], }, { - name: 'squid', - title: 'Squid', - version: '0.3.0', - release: 'experimental', - description: 'Squid Integration', + name: 'ga_beats', + title: 'b. GA, has Beats', + version: '0.0.2', + release: 'ga', + description: 'A package that is GA, not installed, with Beats', type: 'integration', - download: '/epr/squid/squid-0.3.0.zip', - path: '/package/squid/0.3.0', - policy_templates: [ - { - name: 'log', - title: 'Squid', - description: 'Collect Squid logs from syslog or a file.', - }, - ], - id: 'squid', + download: '/epr/ga/not_installed/beats', + path: '/package/ga/not_installed/beats', + id: 'ga_not_installed_beat', status: 'not_installed', + categories: ['azure', 'cloud', 'config_management'], }, { - name: 'stan', - title: 'STAN', - version: '0.2.0', - release: 'beta', - description: 'NATS Streaming Integration', + name: 'ga_installed', + title: 'c. GA, Installed', + version: '0.0.3', + release: 'ga', + description: 'A package that is GA and installed', type: 'integration', - download: '/epr/stan/stan-0.2.0.zip', - path: '/package/stan/0.2.0', - icons: [ - { - src: '/img/stan.svg', - path: '/package/stan/0.2.0/img/stan.svg', - title: 'STAN Logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'stan', - title: 'STAN Logs and Metrics', - description: 'Collect logs and metrics from STAN instances', + download: '/epr/ga/installed', + path: '/package/ga/installed', + id: 'ga_installed', + status: 'installed', + savedObject: { + type: 'epm-packages', + id: 'ga_installed', + attributes: { + installed_kibana: [], + installed_es: [], + package_assets: [], + es_index_patterns: {}, + name: 'ga_installed', + version: '0.0.3', + internal: false, + removable: false, + install_version: '0.0.3', + install_status: 'installed', + install_started_at: '2021-08-25T19:44:37.078Z', + install_source: 'registry', + keep_policies_up_to_date: false, }, - ], - id: 'stan', - status: 'not_installed', + references: [], + coreMigrationVersion: '7.14.0', + updated_at: '2021-08-25T19:44:53.517Z', + version: 'WzczMTIsNF0=', + }, + categories: ['cloud', 'containers'], }, { - name: 'suricata', - title: 'Suricata', - version: '1.2.0', + name: 'ga_installed_update', + title: 'd. GA, Installed, Update', + version: '0.0.4', release: 'ga', - description: 'This Elastic integration collects events from Suricata instances', + description: 'A package that is GA, installed, with update', type: 'integration', - download: '/epr/suricata/suricata-1.2.0.zip', - path: '/package/suricata/1.2.0', - icons: [ - { - src: '/img/suricata.svg', - path: '/package/suricata/1.2.0/img/suricata.svg', - title: 'suricata', - size: '309x309', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'suricata', - title: 'Suricata logs', - description: 'Collect logs from Suricata instances', + download: '/epr/ga/installed/update', + path: '/package/ga/installed/update', + id: 'ga_installed_update', + status: 'installed', + savedObject: { + type: 'epm-packages', + id: 'ga_installed_update', + attributes: { + installed_kibana: [], + installed_es: [], + package_assets: [], + es_index_patterns: {}, + name: 'ga_installed_update', + version: '0.0.1', + internal: false, + removable: false, + install_version: '0.0.1', + install_status: 'installed', + install_started_at: '2021-08-25T19:44:37.078Z', + install_source: 'registry', + keep_policies_up_to_date: false, }, - ], - id: 'suricata', - status: 'not_installed', + references: [], + coreMigrationVersion: '7.14.0', + updated_at: '2021-08-25T19:44:53.517Z', + version: 'WzczMTIsNF0=', + }, + categories: ['cloud', 'crm', 'custom'], }, { - name: 'symantec', - title: 'Symantec AntiVirus/Endpoint Protection', - version: '0.1.2', - release: 'experimental', - description: 'Symantec AntiVirus/Endpoint Protection Integration', + name: 'beta_not_installed', + title: 'e. Beta, Not Installed', + version: '0.0.5', + release: 'beta', + description: 'A package that is Beta, and not installed', type: 'integration', - download: '/epr/symantec/symantec-0.1.2.zip', - path: '/package/symantec/0.1.2', - icons: [ - { - src: '/img/logo.svg', - path: '/package/symantec/0.1.2/img/logo.svg', - title: 'Symantec AntiVirus/Endpoint Protection logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'symantec', - title: 'Symantec AntiVirus/Endpoint Protection logs', - description: 'Collect Symantec AntiVirus/Endpoint Protection logs from syslog or a file.', - }, - ], - id: 'symantec', + download: '/epr/beta/not_installed', + path: '/package/beta/not_installed', + id: 'beta_not_installed', status: 'not_installed', }, { - name: 'synthetics', - title: 'Elastic Synthetics', - version: '0.3.0', + name: 'beta_beats', + title: 'f. Beta, has Beats', + version: '0.0.6', release: 'beta', - description: 'This Elastic integration allows you to monitor the availability of your services', + description: 'A package that is Beta, not installed, with Beats', type: 'integration', - download: '/epr/synthetics/synthetics-0.3.0.zip', - path: '/package/synthetics/0.3.0', - icons: [ - { - src: '/img/uptime-logo-color-64px.svg', - path: '/package/synthetics/0.3.0/img/uptime-logo-color-64px.svg', - size: '16x16', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'synthetics', - title: 'Elastic Synthetics', - description: 'Perform synthetic health checks on network endpoints.', - }, - ], - id: 'synthetics', + download: '/epr/beta/not_installed/beats', + path: '/package/beta/not_installed/beats', + id: 'beta_beats', status: 'not_installed', + categories: ['datastore', 'elastic_stack', 'google_cloud'], }, { - name: 'system', - title: 'System', - version: '1.1.2', - release: 'ga', - description: 'This Elastic integration collects logs and metrics from your servers', + name: 'beta_installed', + title: 'g. Beta, Installed', + version: '0.0.6', + release: 'beta', + description: 'A package that is Beta and installed', type: 'integration', - download: '/epr/system/system-1.1.2.zip', - path: '/package/system/1.1.2', - icons: [ - { - src: '/img/system.svg', - path: '/package/system/1.1.2/img/system.svg', - title: 'system', - size: '1000x1000', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'system', - title: 'System logs and metrics', - description: 'Collect logs and metrics from System instances', - }, - ], - id: 'system', + download: '/epr/beta/installed', + path: '/package/beta/installed', + id: 'beta_installed', status: 'installed', savedObject: { type: 'epm-packages', - id: 'system', + id: 'beta_installed', attributes: { - installed_kibana: [ - { - id: 'system-01c54730-fee6-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-035846a0-a249-11e9-a422-d144027429da', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-0d3f2380-fa78-11e6-ae9b-81e5311e8cab', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-277876d0-fa2c-11e6-bbd3-29c986c96e5a', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-5517a150-f9ce-11e6-8115-a7c18106d86a', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-71f720f0-ff18-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-79ffd6e0-faa0-11e6-947f-177f697178b8', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-8223bed0-b9e9-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-Logs-syslog-dashboard', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-Metrics-system-overview', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-Winlogbeat-dashboard', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-bae11b00-9bfc-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-bb858830-f412-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-d401ef40-a7d5-11e9-a422-d144027429da', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-f49f3170-9ffc-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.dashboard, - }, - { - id: 'system-006d75f0-9c03-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-0620c3d0-bcd4-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-0622da40-9bfd-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-089b85d0-1b16-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-0cb2d940-bcde-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-0f2f5280-feeb-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-102efd20-bcdd-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-117f5a30-9b71-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-12667040-fa80-11e6-a1df-a78bd7504d38', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-162d7ab0-a7d6-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-175a5760-a7d5-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-18348f30-a24d-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-19e123b0-4d5a-11e7-aee5-fdc812cc3bec', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-1aae9140-1b93-11e7-8ada-3df93aab833e', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-1b5f17d0-feea-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-1b6725f0-ff1d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-1f271bc0-231a-11ea-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-2084e300-a884-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-21aadac0-9c0b-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-25f31ee0-9c23-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-26732e20-1b91-11e7-bec4-a5e9ec5cab8b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-26877510-9b72-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-2c71e0f0-9c0d-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-2dc6b820-b9e8-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-2e224660-1b19-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-327417e0-8462-11e7-bab8-bd2f0fb42c54', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-33462600-9b47-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-341ffe70-f9ce-11e6-8115-a7c18106d86a', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-346bb290-fa80-11e6-a1df-a78bd7504d38', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-34f97ee0-1b96-11e7-8ada-3df93aab833e', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-3cec3eb0-f9d3-11e6-8a3e-2b904044ea1d', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-3d65d450-a9c3-11e7-af20-67db8aecb295', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-400b63e0-f49a-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-421f0610-af98-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-4ac8f5f0-bcfe-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-4b683ac0-a7d7-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-4bedf650-9ffd-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-4d546850-1b15-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-4e4bb1e0-1b1b-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-51164310-fa2b-11e6-bbd3-29c986c96e5a', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-522ee670-1b92-11e7-bec4-a5e9ec5cab8b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-546febc0-f49b-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-568a8130-bcde-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-58fb9480-9b46-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-590a60f0-5d87-11e7-8884-1bb4c3b890e4', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5bb93ed0-a249-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5c7af030-fa2a-11e6-bbd3-29c986c96e5a', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5c9ee410-9b74-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5d117970-9ffd-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5d92b100-bce8-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5dd15c00-fa78-11e6-ae9b-81e5311e8cab', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5e19ff80-231c-11ea-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5e7f0ed0-bcd2-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-5eeaafd0-fee7-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-60301890-ff1d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-6b7b9a40-faa1-11e6-86b1-cd7735ff7e23', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-6f0f2ea0-f414-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-729443b0-a7d6-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-7322f9f0-ff1c-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-78b74f30-f9cd-11e6-8115-a7c18106d86a', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-7a329a00-a7d5-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-7cdb1330-4d1a-11e7-a196-69b9a7a020a9', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-7de2e3f0-9b4d-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-804dd400-a248-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-825fdb80-4d1d-11e7-b5f2-2b7c1895bf32', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-83e12df0-1b91-11e7-bec4-a5e9ec5cab8b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-84502430-bce8-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-855899e0-1b1c-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-855957d0-bcdd-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-860706a0-9bfd-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-8ef59f90-6ab8-11ea-896f-0d70f7ec3956', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-8f20c950-bcd4-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-96976150-4d5d-11e7-aa29-87a97a796de6', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-97c70300-ff1c-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-98884120-f49d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-99381c80-4d60-11e7-9a4c-ed99bbcaa42b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-9dd22440-ff1d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-9e534190-f49d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Event-Levels', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Navigation', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Number-of-Events-Over-Time-By-Event-Log', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Number-of-Events', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Sources', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Syslog-events-by-hostname', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Syslog-hostnames-and-processes', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-Top-Event-IDs', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-a13bf640-fee8-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-a3c3f350-9b6d-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-a5f664c0-f49a-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-a79395f0-6aba-11ea-896f-0d70f7ec3956', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-a909b930-685f-11ea-896f-0d70f7ec3956', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-aa31c9d0-9b75-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-ab2d1e90-1b1a-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-ab6f8d80-bce8-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-abd44840-9c0f-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-abf96c10-bcea-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-b5f38780-fee6-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-b89b0c90-9b41-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-bb9cf7a0-f49d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-bc165210-f4b8-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-bf45dc50-ff1a-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-bfa5e400-1b16-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-c2ea73f0-a4bd-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-c359b020-bcdd-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-c5e3cf90-4d60-11e7-9a4c-ed99bbcaa42b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-c6f2ffd0-4d17-11e7-a196-69b9a7a020a9', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-c9d959f0-ff1d-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-caf4d2b0-9b76-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-ce867840-f49e-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-d16bb400-f9cc-11e6-8115-a7c18106d86a', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-d2e80340-4d5c-11e7-aa29-87a97a796de6', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-d3166e80-1b91-11e7-bec4-a5e9ec5cab8b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-d3a5fec0-ff18-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-d56ee420-fa79-11e6-a1df-a78bd7504d38', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-d770b040-9b35-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-da2110c0-bcea-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-da5ffe40-bcd9-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-dc589770-fa2b-11e6-bbd3-29c986c96e5a', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-e0f001c0-1b18-11e7-b09e-037021c4f8df', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-e121b140-fa78-11e6-a1df-a78bd7504d38', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-e20c02d0-9b48-11ea-87e4-49f31ec44891', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-e22c6f40-f498-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-e2516c10-a249-11e9-a422-d144027429da', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-ee0319a0-bcd4-11e9-b6a2-c9b4015c4baf', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-ee292bc0-f499-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-f398d2f0-fa77-11e6-ae9b-81e5311e8cab', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-f42f3b20-fee6-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-fa876300-231a-11ea-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-fe064790-1b1f-11e7-bec4-a5e9ec5cab8b', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-fee83900-f49f-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-ffebe440-f419-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.visualization, - }, - { - id: 'system-06b6b060-7a80-11ea-bc9a-0baf2ca323a3', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-324686c0-fefb-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-62439dc0-f9c9-11e6-a747-6121780e0414', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-6f4071a0-7a78-11ea-bc9a-0baf2ca323a3', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-757510b0-a87f-11e9-a422-d144027429da', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-7e178c80-fee1-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-8030c1b0-fa77-11e6-ae9b-81e5311e8cab', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-9066d5b0-fef2-11e9-8405-516218e3d268', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-Syslog-system-logs', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-b6f321e0-fa25-11e6-bbd3-29c986c96e5a', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-ce71c9a0-a25e-11e9-a422-d144027429da', - type: KibanaSavedObjectType.search, - }, - { - id: 'system-eb0039f0-fa7f-11e6-a1df-a78bd7504d38', - type: KibanaSavedObjectType.search, - }, - ], - installed_es: [ - { - id: 'logs-system.application-1.1.2', - type: ElasticsearchAssetType.ingestPipeline, - }, - { - id: 'logs-system.auth-1.1.2', - type: ElasticsearchAssetType.ingestPipeline, - }, - { - id: 'logs-system.security-1.1.2', - type: ElasticsearchAssetType.ingestPipeline, - }, - { - id: 'logs-system.syslog-1.1.2', - type: ElasticsearchAssetType.ingestPipeline, - }, - { - id: 'logs-system.system-1.1.2', - type: ElasticsearchAssetType.ingestPipeline, - }, - { - id: 'logs-system.application', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'logs-system.application@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'logs-system.auth', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'logs-system.auth@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.core', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.core@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.cpu', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.cpu@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.diskio', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.diskio@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.filesystem', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.filesystem@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.fsstat', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.fsstat@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.load', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.load@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.memory', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.memory@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.network', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.network@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.process', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.process@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.process.summary', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.process.summary@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'logs-system.security', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'logs-system.security@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.socket_summary', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.socket_summary@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'logs-system.syslog', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'logs-system.syslog@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'logs-system.system', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'logs-system.system@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - { - id: 'metrics-system.uptime', - type: ElasticsearchAssetType.indexTemplate, - }, - { - id: 'metrics-system.uptime@custom', - type: ElasticsearchAssetType.componentTemplate, - }, - ], - package_assets: [ - { - id: '24d5bf0e-9d18-5d4c-aab5-e9df683e6c33', - type: 'epm-packages-assets', - }, - { - id: '033fb05a-aacc-5c41-8119-13d52078cf32', - type: 'epm-packages-assets', - }, - { - id: '0b9501d6-2870-5324-b9cf-94ff8cb15e7b', - type: 'epm-packages-assets', - }, - { - id: '88adfac5-87a3-59dd-82f3-be0b4f05c79c', - type: 'epm-packages-assets', - }, - { - id: '91812a40-865b-532c-85bb-c129f0e5470b', - type: 'epm-packages-assets', - }, - { - id: 'bbdae0f8-fbc2-506f-9749-e490ee259cac', - type: 'epm-packages-assets', - }, - { - id: 'a477e3dd-34ff-584e-a5a7-c1c4c2f0cd50', - type: 'epm-packages-assets', - }, - { - id: '9d8784ac-73e3-53d4-8cee-4f89f0ad8510', - type: 'epm-packages-assets', - }, - { - id: 'd4fb583d-0f95-598c-8583-59fc833fad36', - type: 'epm-packages-assets', - }, - { - id: '2503b12c-045c-55a4-9091-c9ec8782248a', - type: 'epm-packages-assets', - }, - { - id: '559fb8fe-6f73-5c7a-ad8d-cd6baba9fd84', - type: 'epm-packages-assets', - }, - { - id: 'cd1d1a1a-f595-5b7f-a416-2f54db379e8e', - type: 'epm-packages-assets', - }, - { - id: '997dc457-7d6e-53c6-b35d-82e6095ac2e5', - type: 'epm-packages-assets', - }, - { - id: '34a2d52c-5041-5c1b-86f7-6edc3384afe9', - type: 'epm-packages-assets', - }, - { - id: '95a53c9e-0a7c-5bb5-9b5c-a2dba086c014', - type: 'epm-packages-assets', - }, - { - id: '1d2390ea-960b-5bd8-ac7c-eb139e57081e', - type: 'epm-packages-assets', - }, - { - id: 'd04ed332-2098-53e5-8b0b-974f4cb8034a', - type: 'epm-packages-assets', - }, - { - id: '568fdd73-d459-5477-9428-e181f7ccf72b', - type: 'epm-packages-assets', - }, - { - id: '97f78283-b529-5993-a841-e8a00eb7da85', - type: 'epm-packages-assets', - }, - { - id: '72db591c-96ed-58ea-a9d7-ee06a2b674d6', - type: 'epm-packages-assets', - }, - { - id: '4102bc21-6624-5a43-90d7-748f0daa6d32', - type: 'epm-packages-assets', - }, - { - id: 'b42ab304-eff7-5996-801f-40bf5577f260', - type: 'epm-packages-assets', - }, - { - id: '32311c4b-847a-5bf0-b24c-1b77ef6e9325', - type: 'epm-packages-assets', - }, - { - id: '6720333f-5f42-58b0-9661-044119397ec1', - type: 'epm-packages-assets', - }, - { - id: 'a021b06f-138b-5927-9abe-3a85d29e6a9a', - type: 'epm-packages-assets', - }, - { - id: '8f2e20d2-dd8f-52f5-b30f-52ef101b32fc', - type: 'epm-packages-assets', - }, - { - id: 'ecd6a951-5656-5c34-b682-b9db70c0502d', - type: 'epm-packages-assets', - }, - { - id: 'ab696da3-6e5b-5da8-b0cd-4d80e95129fd', - type: 'epm-packages-assets', - }, - { - id: 'ddb89b63-b237-58f3-ba8e-ac7dc7d13bce', - type: 'epm-packages-assets', - }, - { - id: 'a45e7e27-141a-5096-8114-bb0b2bae6754', - type: 'epm-packages-assets', - }, - { - id: '4ccce089-3138-54d5-9767-a9434be05289', - type: 'epm-packages-assets', - }, - { - id: 'c5fba17b-85d2-578d-9814-80cb70ad6460', - type: 'epm-packages-assets', - }, - { - id: '8eaba418-f01b-5607-a289-6100b6cda900', - type: 'epm-packages-assets', - }, - { - id: '69d3b6ab-8c55-5eff-bfec-a1d5638d113b', - type: 'epm-packages-assets', - }, - { - id: 'e974ece1-e21d-5ac8-91a2-1d98e6390777', - type: 'epm-packages-assets', - }, - { - id: '1babb631-2aea-5849-ae09-f6438b68694d', - type: 'epm-packages-assets', - }, - { - id: 'ad6ec580-9a98-5f16-b41f-e12586ed98ee', - type: 'epm-packages-assets', - }, - { - id: 'e31da25f-a2ad-5d7a-b8cb-e0c4ff0036e8', - type: 'epm-packages-assets', - }, - { - id: '0b84ce72-ead3-537f-b9f9-79d094d78d4e', - type: 'epm-packages-assets', - }, - { - id: '6dc4776d-f0e7-5b22-ba46-6cd2e82510c0', - type: 'epm-packages-assets', - }, - { - id: '5e341b4d-3a5d-57c7-80ff-af294bf9cc5d', - type: 'epm-packages-assets', - }, - { - id: 'e85af2d2-8d80-5a20-8dc2-43af03df4af9', - type: 'epm-packages-assets', - }, - { - id: '563da411-7931-51df-9086-9e7974d61401', - type: 'epm-packages-assets', - }, - { - id: '4e10bff7-6c0c-55f6-88c0-241844d03eba', - type: 'epm-packages-assets', - }, - { - id: 'fd405691-51b6-55e2-ada4-cfe2e7ac05ee', - type: 'epm-packages-assets', - }, - { - id: '55f2d173-9c93-578a-85db-cc1f8c081a6a', - type: 'epm-packages-assets', - }, - { - id: 'd60b0710-0b00-5bf0-ae84-88fe6867e8b7', - type: 'epm-packages-assets', - }, - { - id: '17b1e231-6c6f-5cdd-aac1-a5d2fb5ad77e', - type: 'epm-packages-assets', - }, - { - id: 'b14839c1-f0b1-5972-a33d-c27fffdecdea', - type: 'epm-packages-assets', - }, - { - id: '5c90f8d0-1303-52c9-98fd-c887a10b5156', - type: 'epm-packages-assets', - }, - { - id: '576f2cb7-c3f7-54cd-8867-7f5db0ea0181', - type: 'epm-packages-assets', - }, - { - id: 'f1d3b54c-ac5c-5b16-bbc8-6fa7a30a830d', - type: 'epm-packages-assets', - }, - { - id: '140002b7-becc-5d5e-94cd-6d0d2509fe76', - type: 'epm-packages-assets', - }, - { - id: '00d83ffe-f12c-5b14-bf88-4dd56f61035d', - type: 'epm-packages-assets', - }, - { - id: '5bac3cbc-0bfd-5a90-8705-4ce8d009725d', - type: 'epm-packages-assets', - }, - { - id: '2e69cfa6-1114-5b12-bb3d-1c0c03ee1342', - type: 'epm-packages-assets', - }, - { - id: 'c222cb4c-081e-5177-9ba3-d74da589ff3f', - type: 'epm-packages-assets', - }, - { - id: '57bccf05-7422-5d2d-bb77-7483568c9224', - type: 'epm-packages-assets', - }, - { - id: '65891658-69fd-5c65-a6da-49129ce35bad', - type: 'epm-packages-assets', - }, - { - id: 'ed38f380-d847-51a5-9642-fc7cabaa05ca', - type: 'epm-packages-assets', - }, - { - id: '4d941e9d-48b2-5d34-8367-e42b94749731', - type: 'epm-packages-assets', - }, - { - id: '97d561ac-86ec-5897-b81c-497bdc2a1161', - type: 'epm-packages-assets', - }, - { - id: 'd487aacb-1cfe-5f61-8a15-11537fe0697c', - type: 'epm-packages-assets', - }, - { - id: '4db2b1d9-a85d-5e63-92f2-1b6c2b78cf06', - type: 'epm-packages-assets', - }, - { - id: '03709276-036a-5e07-bfeb-38b2b64139f9', - type: 'epm-packages-assets', - }, - { - id: '7c3b4348-d34c-5e15-bf53-1ed674b05b21', - type: 'epm-packages-assets', - }, - { - id: 'f01f1b2e-0da0-562e-9b45-7522f7c3e77b', - type: 'epm-packages-assets', - }, - { - id: '2d997745-8418-561e-86f4-788f2eb4fb0c', - type: 'epm-packages-assets', - }, - { - id: '03a1c87a-a43b-5257-aaf5-3be4f4d632ba', - type: 'epm-packages-assets', - }, - { - id: 'a37af953-176e-5e32-85c5-da9671ce4f2e', - type: 'epm-packages-assets', - }, - { - id: '784c1144-fcdb-5684-9aa5-76ff1bc47324', - type: 'epm-packages-assets', - }, - { - id: '5c874611-e4ec-5353-8d4c-7841f09c3051', - type: 'epm-packages-assets', - }, - { - id: 'ddf93bfe-6d21-57d4-be98-cdf365bb3f13', - type: 'epm-packages-assets', - }, - { - id: '417e458b-3741-5de1-b5e8-501a1a9e0f6b', - type: 'epm-packages-assets', - }, - { - id: '136bbf6d-0a63-5088-8685-2c6d26f03f59', - type: 'epm-packages-assets', - }, - { - id: '1c913ab0-9afa-5f79-865e-e44a47d066f1', - type: 'epm-packages-assets', - }, - { - id: 'f74391c4-6e8a-5a27-9486-8525f52b36c5', - type: 'epm-packages-assets', - }, - { - id: '087058d0-e7bf-59d0-896a-0dcb9d9a570b', - type: 'epm-packages-assets', - }, - { - id: 'ce860d2b-f771-5a08-8225-7cf1afd96fcd', - type: 'epm-packages-assets', - }, - { - id: '3a06e9da-ebc7-5531-a980-23e3cb86de02', - type: 'epm-packages-assets', - }, - { - id: '711f1455-9e07-5c3a-a11f-f362c08fb452', - type: 'epm-packages-assets', - }, - { - id: 'f574e863-e38a-5a0d-b578-0ed946b5468a', - type: 'epm-packages-assets', - }, - { - id: '29181820-83c6-5127-988a-269451896254', - type: 'epm-packages-assets', - }, - { - id: '763a3348-e7cb-546a-ad86-81958a1689b9', - type: 'epm-packages-assets', - }, - { - id: 'a0dec889-17d3-5ac2-b95d-04bbfdce3157', - type: 'epm-packages-assets', - }, - { - id: 'db23f433-b1e1-54ba-9afa-02e70163e83c', - type: 'epm-packages-assets', - }, - { - id: '5f11a1bf-597e-5487-a095-7659c392a5bb', - type: 'epm-packages-assets', - }, - { - id: '2e262321-fdb2-593b-a72b-3db407216633', - type: 'epm-packages-assets', - }, - { - id: '58f5919e-5785-5fef-90e8-38395e0038db', - type: 'epm-packages-assets', - }, - { - id: 'be985ede-d853-5e83-900b-df3e5aa9bd3a', - type: 'epm-packages-assets', - }, - { - id: '79d24ce5-e559-55d4-a472-66d264c25ab6', - type: 'epm-packages-assets', - }, - { - id: 'e3efa70d-c7da-5989-b258-887a79bf39de', - type: 'epm-packages-assets', - }, - { - id: '5cc41639-8151-5dcb-91db-9cbc6915b1d3', - type: 'epm-packages-assets', - }, - { - id: '083e964e-4e48-5271-822b-8f7b2dce4dd8', - type: 'epm-packages-assets', - }, - { - id: '8d79b461-55a3-53e6-9d6b-b92864a7d5f0', - type: 'epm-packages-assets', - }, - { - id: '7e761fd5-62c9-5f77-9427-213578f7498f', - type: 'epm-packages-assets', - }, - { - id: '0e06037c-ce0f-50d2-a16a-a32e5f632da8', - type: 'epm-packages-assets', - }, - { - id: 'a6a05d73-19a4-52ba-b3d1-02eaaf3d7b9b', - type: 'epm-packages-assets', - }, - { - id: 'df5075ba-5910-566f-ba84-84bb8c692cc9', - type: 'epm-packages-assets', - }, - { - id: '7f9ae2a5-e086-50c9-924b-45dddb8b76d6', - type: 'epm-packages-assets', - }, - { - id: 'b486d488-4f6c-5f29-acf2-f793369d6188', - type: 'epm-packages-assets', - }, - { - id: '389a7808-4698-5039-87cb-6ab4f7e1eae0', - type: 'epm-packages-assets', - }, - { - id: 'e02a82bf-bf0b-5e92-9b5a-8285ad1a52eb', - type: 'epm-packages-assets', - }, - { - id: '9379b6e7-e5f5-5ba9-b174-9125cb1ee76c', - type: 'epm-packages-assets', - }, - { - id: '4fd4d826-5ea7-58a7-a246-2b449569f602', - type: 'epm-packages-assets', - }, - { - id: '231f9666-6a08-53d2-a0ab-8da2b82f7ada', - type: 'epm-packages-assets', - }, - { - id: 'b8e0ada0-cb83-54ee-b924-f088c198ecc7', - type: 'epm-packages-assets', - }, - { - id: '2dbdc626-9a1b-5576-a8c6-aa182c97d228', - type: 'epm-packages-assets', - }, - { - id: '1c12a013-82b5-52da-b873-94798ec7d2ce', - type: 'epm-packages-assets', - }, - { - id: '9d9f32b2-eb0f-584f-972e-a326879e0bfe', - type: 'epm-packages-assets', - }, - { - id: 'f1431004-2baa-54a0-b791-318d72757154', - type: 'epm-packages-assets', - }, - { - id: 'cc411f61-3734-5fb4-97c5-c61ff2e1b05a', - type: 'epm-packages-assets', - }, - { - id: '1719a42f-f653-55a6-b879-fa7bca79f77f', - type: 'epm-packages-assets', - }, - { - id: '8d29b0e4-042a-556a-ac3f-9c4de92cf77e', - type: 'epm-packages-assets', - }, - { - id: 'd74b45f5-001f-5ec1-8665-e7e95b0f233d', - type: 'epm-packages-assets', - }, - { - id: '55fdbd3b-2f4a-5aec-9224-fb34c4f1c212', - type: 'epm-packages-assets', - }, - { - id: 'd7215663-4278-5148-a57b-befecdc2123f', - type: 'epm-packages-assets', - }, - { - id: 'e1c31072-ca11-5a08-b192-c6b6b330476c', - type: 'epm-packages-assets', - }, - { - id: '7345876f-234b-5bc1-bddd-125e83b60255', - type: 'epm-packages-assets', - }, - { - id: 'd3f8cdbd-105c-59c7-b5d8-34bf18b0cb46', - type: 'epm-packages-assets', - }, - { - id: 'f070a7df-6dae-58d8-96f2-d030c4cc5184', - type: 'epm-packages-assets', - }, - { - id: '9b7a9c7a-c925-51fa-8942-af378816c0bf', - type: 'epm-packages-assets', - }, - { - id: '9af0ba7a-52a7-56a8-a2f4-0d8fef143757', - type: 'epm-packages-assets', - }, - { - id: '91b93121-5088-5930-b9ac-fa9a643537ec', - type: 'epm-packages-assets', - }, - { - id: 'b9ed8fdd-58f1-5523-9e74-f20cc12d787b', - type: 'epm-packages-assets', - }, - { - id: '6e111583-649e-5edf-b66f-01f43467511a', - type: 'epm-packages-assets', - }, - { - id: '2f72a5e2-6c88-5a63-a599-5862799c6ca9', - type: 'epm-packages-assets', - }, - { - id: '6b12bc40-b5a9-52ad-b797-a159448652fb', - type: 'epm-packages-assets', - }, - { - id: '26d03b35-8b9f-5fde-820d-6267f1aebf53', - type: 'epm-packages-assets', - }, - { - id: '059f27cd-e074-5f10-bd40-b0760788ee91', - type: 'epm-packages-assets', - }, - { - id: '6c580e87-8fc1-54f6-85ab-9393e0e4d37d', - type: 'epm-packages-assets', - }, - { - id: '666e0e06-7597-5c4a-8195-d7972b8f2e08', - type: 'epm-packages-assets', - }, - { - id: '51a0f0e9-2c37-5fb0-8b66-cb6178c52801', - type: 'epm-packages-assets', - }, - { - id: '7b26a89b-a12b-5270-aa62-341b202f8fe8', - type: 'epm-packages-assets', - }, - { - id: '958fad54-be5f-5179-82fa-8f621a9323f0', - type: 'epm-packages-assets', - }, - { - id: '0964f86c-3118-5bc1-8af8-7db1d0394ef0', - type: 'epm-packages-assets', - }, - { - id: 'da7acbc4-da77-5f87-a0f2-8e4a3f298172', - type: 'epm-packages-assets', - }, - { - id: 'b051c802-cadd-543f-99d2-a9a1d7fba243', - type: 'epm-packages-assets', - }, - { - id: 'af53017a-2dba-5fd7-8eea-7752e67e388a', - type: 'epm-packages-assets', - }, - { - id: '6f9cbba4-a2fb-580b-a9d5-73a79dea8263', - type: 'epm-packages-assets', - }, - { - id: '9b7019a3-66fb-5a45-bee2-00242a1e1770', - type: 'epm-packages-assets', - }, - { - id: 'f1d12e9e-af81-56d7-81d7-596adb6d1146', - type: 'epm-packages-assets', - }, - { - id: 'cd59bacd-892e-5202-9641-a02a720fbdb2', - type: 'epm-packages-assets', - }, - { - id: '4bbda699-6819-58f4-ac75-a59adb263ebe', - type: 'epm-packages-assets', - }, - { - id: '5fad7deb-4489-5ac5-b9fb-5b847204b9ac', - type: 'epm-packages-assets', - }, - { - id: '12aca1cb-f4bb-5878-bfee-d7d45a8c0e81', - type: 'epm-packages-assets', - }, - { - id: 'f3ab06ad-c1f1-556c-92a1-173e357afb8c', - type: 'epm-packages-assets', - }, - { - id: '165aab12-d901-5568-8f9a-ab5b74e54867', - type: 'epm-packages-assets', - }, - { - id: '87d7174f-dc0a-5f90-a98c-b4777035360c', - type: 'epm-packages-assets', - }, - { - id: '0975161e-aa3a-59ac-bf20-4811844a8aab', - type: 'epm-packages-assets', - }, - { - id: '44d5ce37-7b61-5494-9685-b56968bac54d', - type: 'epm-packages-assets', - }, - { - id: 'e2e58028-d78d-5702-bb30-8bb081a457ea', - type: 'epm-packages-assets', - }, - { - id: 'bda60661-3ee7-5c69-9ef5-5cfd55ff1cae', - type: 'epm-packages-assets', - }, - { - id: 'f800cd09-c76e-5d2e-b639-da9fa99520eb', - type: 'epm-packages-assets', - }, - { - id: '80aa97ca-d0bc-5cab-afa8-1a8c11682edd', - type: 'epm-packages-assets', - }, - { - id: 'f815750f-f03c-5cb8-a45e-20b9a3a7bc22', - type: 'epm-packages-assets', - }, - { - id: '6f8d92f7-80f4-584c-81a6-50543701adb9', - type: 'epm-packages-assets', - }, - { - id: '93a1a4f5-0554-5089-a59b-6ca3319459ad', - type: 'epm-packages-assets', - }, - { - id: '9ff13f94-2687-520e-be62-c6d0b2c89218', - type: 'epm-packages-assets', - }, - { - id: '672c62d6-c24a-52ba-904e-3a502d591e79', - type: 'epm-packages-assets', - }, - { - id: 'b90ac874-628b-57ca-9663-dca9632a8c45', - type: 'epm-packages-assets', - }, - { - id: '3dbe7093-69aa-517e-8301-405e48e59051', - type: 'epm-packages-assets', - }, - { - id: '19752e35-ee5c-5683-8a9b-d129ff71c162', - type: 'epm-packages-assets', - }, - { - id: '93e79ab8-6d64-5d99-974d-89521c354b45', - type: 'epm-packages-assets', - }, - { - id: '46d66f9e-6fac-5004-9bd0-2d6078f0739d', - type: 'epm-packages-assets', - }, - { - id: '50257938-fd37-5d8b-8ae9-93ea39a47e9c', - type: 'epm-packages-assets', - }, - { - id: 'b799ffc1-7e6e-5da6-b6cd-842bda37d01f', - type: 'epm-packages-assets', - }, - { - id: 'a7a292ea-4e3f-5c1a-bb9a-3b466165a429', - type: 'epm-packages-assets', - }, - { - id: 'aa66e955-a443-5fe5-96c3-00199a9fb5d0', - type: 'epm-packages-assets', - }, - { - id: '39a22cf9-b766-5241-ad8b-d18b9aa8df50', - type: 'epm-packages-assets', - }, - { - id: '8d0b51b9-2bb4-575a-a149-51733de8003a', - type: 'epm-packages-assets', - }, - { - id: '60c3f393-3171-5890-8239-0c631fc3a14a', - type: 'epm-packages-assets', - }, - { - id: '69cd3134-5051-548f-9758-494c6354ff35', - type: 'epm-packages-assets', - }, - { - id: '6b556824-89f1-5d3b-8bee-d59ecf874c11', - type: 'epm-packages-assets', - }, - { - id: 'dc73b22f-a8ac-5170-8cbb-7d4d38d8bc00', - type: 'epm-packages-assets', - }, - { - id: '3b6cc790-f311-5f79-8bbb-d658d81edd38', - type: 'epm-packages-assets', - }, - { - id: '040a0b65-35a6-5813-92e2-feeb6a40b018', - type: 'epm-packages-assets', - }, - { - id: '188f4e4a-45c1-5cc7-8278-feed4336bec6', - type: 'epm-packages-assets', - }, - { - id: '54c52c7a-baec-5382-802e-33c6870d59f9', - type: 'epm-packages-assets', - }, - { - id: '573ec1c9-da4d-57ef-82be-967aef48d83f', - type: 'epm-packages-assets', - }, - { - id: '6c737ba6-11c0-587e-b8e0-ec2e866371e1', - type: 'epm-packages-assets', - }, - { - id: '26a2a1b7-38d1-5740-9a27-bd17e027f7b2', - type: 'epm-packages-assets', - }, - { - id: '051fdd40-0212-5321-aeeb-1728e7ae53d7', - type: 'epm-packages-assets', - }, - { - id: '04c6eaec-4640-50b0-9efe-a642b4aae216', - type: 'epm-packages-assets', - }, - { - id: 'f3a8de34-d8f4-50ca-a886-43baf333f5be', - type: 'epm-packages-assets', - }, - { - id: 'd9368d92-e820-597f-9218-b2aa932c434b', - type: 'epm-packages-assets', - }, - { - id: 'd29075e3-40d0-580a-aaec-b03cdb617cc0', - type: 'epm-packages-assets', - }, - { - id: 'f1a54648-7c44-5c4f-8424-4042cca607e6', - type: 'epm-packages-assets', - }, - { - id: '2861cc7c-b7a2-5b15-b278-4db559dc0a5d', - type: 'epm-packages-assets', - }, - { - id: '51d0ae10-229b-5899-9da5-9121b44a86bf', - type: 'epm-packages-assets', - }, - { - id: 'dcb7e0df-b8e6-5734-a66d-1ce6bc7c0223', - type: 'epm-packages-assets', - }, - { - id: '9e989e61-490b-526d-9e54-3f91c36e79c7', - type: 'epm-packages-assets', - }, - { - id: 'cd257f39-46bf-5f9c-aa3c-39f0e0ca7597', - type: 'epm-packages-assets', - }, - { - id: '33853dbc-7979-5d20-aa98-160e5ebc4244', - type: 'epm-packages-assets', - }, - { - id: '9048c9e2-18a3-5119-981a-d7ca191be801', - type: 'epm-packages-assets', - }, - { - id: '1a1733e0-9f09-5ac6-a419-21d2f1b9666e', - type: 'epm-packages-assets', - }, - { - id: 'f7ac8629-a4f6-5c98-90fd-b0477fccba74', - type: 'epm-packages-assets', - }, - { - id: '68520af7-8007-5905-899c-072de167f361', - type: 'epm-packages-assets', - }, - { - id: 'a2b18338-7df4-51a2-a73d-1a8b437515b8', - type: 'epm-packages-assets', - }, - { - id: '0fc2b9aa-eca6-538c-a837-5201dcb11a71', - type: 'epm-packages-assets', - }, - { - id: '92836dfc-f2c6-5bb2-a894-1380e17b43f8', - type: 'epm-packages-assets', - }, - { - id: '4c0a30e6-c549-569b-b30c-357a30b8da3d', - type: 'epm-packages-assets', - }, - { - id: '2668e8ff-b1df-5101-aaf0-7a5b05c366d3', - type: 'epm-packages-assets', - }, - { - id: 'cf821d9d-2e6c-551a-b531-9ce5c435b7e4', - type: 'epm-packages-assets', - }, - { - id: 'dedc165b-ae21-5ac4-a7b3-7c3edc6630ba', - type: 'epm-packages-assets', - }, - { - id: '31e07239-4a6e-57ec-89b5-583d6b2709a5', - type: 'epm-packages-assets', - }, - { - id: '93ffa150-4107-5505-9236-7fdcec538c4f', - type: 'epm-packages-assets', - }, - { - id: '0d97ad87-b383-5ea8-b801-25b680c2d7d0', - type: 'epm-packages-assets', - }, - { - id: '8aa84a63-fb84-50f3-bd3f-c7bb29a89af6', - type: 'epm-packages-assets', - }, - { - id: 'c85d8839-6640-5a78-9ea6-7f03ba9fc51a', - type: 'epm-packages-assets', - }, - { - id: 'c074a913-ea70-5480-b7ed-07a9a93f40cf', - type: 'epm-packages-assets', - }, - { - id: 'fbcec175-4095-5e91-ad9e-437a1ac9584f', - type: 'epm-packages-assets', - }, - { - id: '5e3614f8-067a-54bc-b951-b3ea030b9be3', - type: 'epm-packages-assets', - }, - { - id: '2974eddc-3a5f-5a09-bc62-93538b50fc70', - type: 'epm-packages-assets', - }, - { - id: 'bf6d6ef7-7789-5b9c-aae5-6fe8db72cb24', - type: 'epm-packages-assets', - }, - { - id: 'd67e0090-fa3b-5e61-a904-1ad701254182', - type: 'epm-packages-assets', - }, - { - id: '9f9f0f9c-8d63-5665-9fb7-8a9f45fe247a', - type: 'epm-packages-assets', - }, - { - id: '23b847fa-f386-5d10-b0b7-504831bf03d3', - type: 'epm-packages-assets', - }, - { - id: '48e9edd3-6275-5651-94dc-f84d59c5e000', - type: 'epm-packages-assets', - }, - { - id: '2db92138-78cc-5d57-954f-7384e50e0d46', - type: 'epm-packages-assets', - }, - { - id: '06f39986-ae21-5f3e-b784-01e82f323dc2', - type: 'epm-packages-assets', - }, - { - id: '2de02893-ff19-5910-9f99-6dda03d7c5e8', - type: 'epm-packages-assets', - }, - { - id: 'f4ab1085-e651-58e3-a3f1-61013e49c52a', - type: 'epm-packages-assets', - }, - { - id: 'e05ef072-d40c-5e96-95f9-9e5d6b8fdfd8', - type: 'epm-packages-assets', - }, - { - id: '6a9e30e1-6e29-51ca-b139-b9455471c4aa', - type: 'epm-packages-assets', - }, - { - id: '25fe3eb0-81f5-50d3-96bf-1cf520fb5f2b', - type: 'epm-packages-assets', - }, - { - id: '3b2ff5fb-e011-5996-b4d8-1350dea44011', - type: 'epm-packages-assets', - }, - { - id: '1c403bef-ee6d-5914-9821-ac8493b69842', - type: 'epm-packages-assets', - }, - { - id: '8b020f17-1522-552d-8e6b-c1dd232dcf84', - type: 'epm-packages-assets', - }, - { - id: 'e31a648e-9344-5837-919d-60038e37bcc2', - type: 'epm-packages-assets', - }, - { - id: '5b9412ab-3b86-53e3-9d37-ba297e3e9d82', - type: 'epm-packages-assets', - }, - { - id: 'd0517d7f-d352-5d42-a69b-be1e8f29facc', - type: 'epm-packages-assets', - }, - { - id: '31b00140-beb8-59b4-bab8-a2b3110ee028', - type: 'epm-packages-assets', - }, - { - id: '7a14010e-0af3-52f9-9cc6-4abbd711a2ec', - type: 'epm-packages-assets', - }, - { - id: '42bf2853-8f0b-51ed-a83f-43a0eef0e69c', - type: 'epm-packages-assets', - }, - { - id: '6ab1c44b-fb31-58f2-bea3-89610bb85033', - type: 'epm-packages-assets', - }, - { - id: 'b40691b2-a9fa-5ed8-92b6-dddcba93778c', - type: 'epm-packages-assets', - }, - { - id: '8efe38d9-648a-5e7d-8491-51d24406ae87', - type: 'epm-packages-assets', - }, - { - id: '2c02d373-6c2c-5312-9a6d-4c823e95cce9', - type: 'epm-packages-assets', - }, - { - id: '3976bb6c-5bc6-586e-92a9-a94ac1844a80', - type: 'epm-packages-assets', - }, - { - id: '036f7167-6000-5a73-8c21-3dc079973054', - type: 'epm-packages-assets', - }, - { - id: '7c7f845d-4824-5387-94ac-589d1c1b8536', - type: 'epm-packages-assets', - }, - { - id: 'af7d2530-6254-50bf-8d6d-1fdb86bbea12', - type: 'epm-packages-assets', - }, - { - id: 'cb22ffac-9010-56b5-bb51-feeb1ff49903', - type: 'epm-packages-assets', - }, - { - id: '526b63f6-76da-5cb6-a511-8b6ef368d8be', - type: 'epm-packages-assets', - }, - { - id: '02d6549b-7f9f-5360-bf21-183cb9065b50', - type: 'epm-packages-assets', - }, - { - id: '918f71de-1ab1-5662-a50e-a1a235f9cdfe', - type: 'epm-packages-assets', - }, - { - id: '8d0c593b-c7ae-5190-ba74-caeefb473f06', - type: 'epm-packages-assets', - }, - { - id: 'b4928fed-4b26-5721-8982-8e985c54c151', - type: 'epm-packages-assets', - }, - { - id: 'dff8573e-b91b-56ee-99e1-7b605e4e0b78', - type: 'epm-packages-assets', - }, - { - id: '999ecb6a-d0ef-5f09-b93b-f5ef5041e928', - type: 'epm-packages-assets', - }, - { - id: '30a65433-4678-5252-8588-1c2d5eb06c82', - type: 'epm-packages-assets', - }, - { - id: '86ab9714-31e7-5625-98c7-d303eac35336', - type: 'epm-packages-assets', - }, - { - id: '3d13b34b-1254-5feb-bf46-84ed005468ba', - type: 'epm-packages-assets', - }, - { - id: '6c1f565a-7fb4-5b3e-a4bb-a8072306f869', - type: 'epm-packages-assets', - }, - { - id: '6c305802-12f6-58fd-9979-fc52fc494c74', - type: 'epm-packages-assets', - }, - { - id: 'b7cfc3ba-0e9d-50dc-b52a-6d2f91f94d27', - type: 'epm-packages-assets', - }, - { - id: 'abc29ba1-5bf2-5685-a518-e8ab9b5ab174', - type: 'epm-packages-assets', - }, - { - id: '85a9890a-7c64-5113-9ca8-0da157eefb1a', - type: 'epm-packages-assets', - }, - { - id: '27661e6f-a30a-5365-bd1d-2cb1b5c0d41a', - type: 'epm-packages-assets', - }, - { - id: '3b9ddf7f-133c-53c4-bb01-e32e18896ae5', - type: 'epm-packages-assets', - }, - { - id: '08811d02-e3ed-5645-a2a8-f300fe7d166c', - type: 'epm-packages-assets', - }, - { - id: '8f6eb04b-4313-5d5a-ac05-354914d0f98d', - type: 'epm-packages-assets', - }, - { - id: '8a871681-368e-5039-b739-4048738a1d62', - type: 'epm-packages-assets', - }, - { - id: '46e7dfa4-17d7-596f-8cba-b675155e527b', - type: 'epm-packages-assets', - }, - { - id: 'a67744b6-e2ee-51f7-b366-0a90acd0db55', - type: 'epm-packages-assets', - }, - { - id: 'ddf46bcf-9a54-5703-b900-e0eab0387954', - type: 'epm-packages-assets', - }, - { - id: '42fd7566-ac3c-58f9-95f0-f1113bd6c7b4', - type: 'epm-packages-assets', - }, - { - id: '7b4f945b-99a0-5660-8707-2669e601f1de', - type: 'epm-packages-assets', - }, - { - id: 'c902879a-cd96-5911-b5c3-b59a299ad537', - type: 'epm-packages-assets', - }, - { - id: '74aee54b-85e5-5022-92ff-f185cfc4206a', - type: 'epm-packages-assets', - }, - { - id: 'aeec412b-aa37-5f4c-84ae-d9c2ecab908d', - type: 'epm-packages-assets', - }, - { - id: '1a21a3d5-c1cf-5e91-85e9-208b8b151d73', - type: 'epm-packages-assets', - }, - { - id: '980d1022-5fa3-5ba0-bb2e-d69404dd6bef', - type: 'epm-packages-assets', - }, - { - id: 'e4473aed-5c33-5dea-a2d3-a91ac13117d8', - type: 'epm-packages-assets', - }, - ], - es_index_patterns: { - application: 'logs-system.application-*', - auth: 'logs-system.auth-*', - core: 'metrics-system.core-*', - cpu: 'metrics-system.cpu-*', - diskio: 'metrics-system.diskio-*', - filesystem: 'metrics-system.filesystem-*', - fsstat: 'metrics-system.fsstat-*', - load: 'metrics-system.load-*', - memory: 'metrics-system.memory-*', - network: 'metrics-system.network-*', - process: 'metrics-system.process-*', - process_summary: 'metrics-system.process.summary-*', - security: 'logs-system.security-*', - socket_summary: 'metrics-system.socket_summary-*', - syslog: 'logs-system.syslog-*', - system: 'logs-system.system-*', - uptime: 'metrics-system.uptime-*', - }, - name: 'system', - version: '1.1.2', + installed_kibana: [], + installed_es: [], + package_assets: [], + es_index_patterns: {}, + name: 'beta_installed', + version: '0.0.6', internal: false, removable: false, - install_version: '1.1.2', + install_version: '0.0.6', install_status: 'installed', - install_started_at: '2021-08-25T19:44:43.380Z', + install_started_at: '2021-08-25T19:44:37.078Z', install_source: 'registry', keep_policies_up_to_date: false, }, references: [], coreMigrationVersion: '7.14.0', - updated_at: '2021-08-25T19:45:12.096Z', - version: 'Wzc3NjUsNF0=', - // score: 0, TODO: this is not represented in any type, but is returned by the API + updated_at: '2021-08-25T19:44:53.517Z', + version: 'WzczMTIsNF0=', }, + categories: ['elastic_stack', 'languages'], }, { - name: 'tomcat', - title: 'Apache Tomcat', - version: '0.3.0', - release: 'experimental', - description: 'Apache Tomcat Integration', + name: 'beta_installed_update', + title: 'h. Beta, Installed, Update', + version: '0.0.7', + release: 'beta', + description: 'A package that is Beta, installed, with update', type: 'integration', - download: '/epr/tomcat/tomcat-0.3.0.zip', - path: '/package/tomcat/0.3.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/tomcat/0.3.0/img/logo.svg', - title: 'Apache Tomcat logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'log', - title: 'Apache Tomcat', - description: 'Collect Apache Tomcat logs from syslog or a file.', + download: '/epr/beta/installed', + path: '/package/beta/installed', + id: 'beta_installed_update', + status: 'installed', + savedObject: { + type: 'epm-packages', + id: 'beta_installed_update', + attributes: { + installed_kibana: [], + installed_es: [], + package_assets: [], + es_index_patterns: {}, + name: 'beta_installed_update', + version: '0.0.3', + internal: false, + removable: false, + install_version: '0.0.3', + install_status: 'installed', + install_started_at: '2021-08-25T19:44:37.078Z', + install_source: 'registry', + keep_policies_up_to_date: false, }, - ], - id: 'tomcat', - status: 'not_installed', + references: [], + coreMigrationVersion: '7.14.0', + updated_at: '2021-08-25T19:44:53.517Z', + version: 'WzczMTIsNF0=', + }, + categories: ['message_queue', 'monitoring'], }, { - name: 'traefik', - title: 'Traefik', - version: '0.3.0', + name: 'exp_not_installed', + title: 'i. Experimental, Not Installed', + version: '0.0.8', release: 'experimental', - description: 'Traefik Integration', - type: 'integration', - download: '/epr/traefik/traefik-0.3.0.zip', - path: '/package/traefik/0.3.0', - icons: [ - { - src: '/img/traefik.svg', - path: '/package/traefik/0.3.0/img/traefik.svg', - title: 'traefik', - size: '259x296', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'traefik', - title: 'Traefik logs and metrics', - description: 'Collect logs and metrics from Traefik instances', - }, - ], - id: 'traefik', - status: 'not_installed', - }, - { - name: 'windows', - title: 'Windows', - version: '1.0.0', - release: 'ga', - description: 'Windows Integration', + description: 'A package that is Experimental and not installed', type: 'integration', - download: '/epr/windows/windows-1.0.0.zip', - path: '/package/windows/1.0.0', - icons: [ - { - src: '/img/logo_windows.svg', - path: '/package/windows/1.0.0/img/logo_windows.svg', - title: 'logo windows', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'windows', - title: 'Windows logs and metrics', - description: 'Collect logs and metrics from Windows instances', - }, - ], - id: 'windows', + download: '/epr/exp/not_installed', + path: '/package/exp/not_installed', + id: 'exp_not_installed', status: 'not_installed', + categories: ['monitoring', 'network', 'notification'], }, { - name: 'winlog', - title: 'Custom Windows event logs', - version: '0.4.0', + name: 'exp_beats', + title: 'j. Experimental, has Beats', + version: '0.0.9', release: 'experimental', - description: 'This Elastic integration collects custom Windows event logs', - type: 'integration', - download: '/epr/winlog/winlog-0.4.0.zip', - path: '/package/winlog/0.4.0', - icons: [ - { - src: '/img/logo_windows.svg', - path: '/package/winlog/0.4.0/img/logo_windows.svg', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'winlogs', - title: 'Custom Windows event logs', - description: 'Collect your custom Windows event logs.', - }, - ], - id: 'winlog', - status: 'not_installed', - }, - { - name: 'zeek', - title: 'Zeek', - version: '1.3.0', - release: 'ga', - description: 'This Elastic integration collects logs from Zeek', + description: 'A package that is Experimental and not installed', type: 'integration', - download: '/epr/zeek/zeek-1.3.0.zip', - path: '/package/zeek/1.3.0', - icons: [ - { - src: '/img/zeek.svg', - path: '/package/zeek/1.3.0/img/zeek.svg', - title: 'zeek', - size: '214x203', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'zeek', - title: 'Zeek logs', - description: 'Collect logs from Zeek instances', - }, - ], - id: 'zeek', + download: '/epr/exp/not_installed/beats', + path: '/package/exp/not_installed/beats', + id: 'exp_beats', status: 'not_installed', - }, - { - name: 'zerofox', - title: 'ZeroFox', - version: '0.1.1', - release: 'experimental', - description: 'ZeroFox Cloud Platform', - type: 'integration', - download: '/epr/zerofox/zerofox-0.1.1.zip', - path: '/package/zerofox/0.1.1', - icons: [ - { - src: '/img/logo.svg', - path: '/package/zerofox/0.1.1/img/logo.svg', - title: 'logo ZeroFox', - size: '32x32', - type: 'image/svg+xml', - }, - ], policy_templates: [ { - name: 'zerofox', - title: 'ZeroFox Alerts', - description: 'Collect alert from the ZeroFox API', + name: '', + description: '', + title: '', + categories: ['datastore'], }, ], - id: 'zerofox', - status: 'not_installed', + categories: ['version_control', 'web'], }, { - name: 'zookeeper', - title: 'ZooKeeper', - version: '0.3.1', + name: 'exp_installed', + title: 'k. Experimental, Installed', + version: '0.0.10', release: 'experimental', - description: 'ZooKeeper Integration', - type: 'integration', - download: '/epr/zookeeper/zookeeper-0.3.1.zip', - path: '/package/zookeeper/0.3.1', - icons: [ - { - src: '/img/zookeeper.svg', - path: '/package/zookeeper/0.3.1/img/zookeeper.svg', - title: 'zookeeper', - size: '754x754', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'zookeeper', - title: 'ZooKeeper metrics', - description: 'Collect metrics from ZooKeeper instances', - }, - ], - id: 'zookeeper', - status: 'not_installed', - }, - { - name: 'zoom', - title: 'Zoom', - version: '0.6.0', - release: 'beta', - description: 'This Elastic integration collects logs from Zoom', + description: 'A package that is experimental and installed', type: 'integration', - download: '/epr/zoom/zoom-0.6.0.zip', - path: '/package/zoom/0.6.0', - icons: [ - { - src: '/img/zoom_blue.svg', - path: '/package/zoom/0.6.0/img/zoom_blue.svg', - title: 'Zoom', - size: '516x240', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'zoom', - title: 'Zoom logs', - description: 'Collect logs from Zoom instances', + download: '/epr/exp/installed', + path: '/package/exp/installed', + id: 'exp_installed', + status: 'installed', + savedObject: { + type: 'epm-packages', + id: 'exp_installed', + attributes: { + installed_kibana: [], + installed_es: [], + package_assets: [], + es_index_patterns: {}, + name: 'exp_installed', + version: '0.0.10', + internal: false, + removable: false, + install_version: '0.0.10', + install_status: 'installed', + install_started_at: '2021-08-25T19:44:37.078Z', + install_source: 'registry', + keep_policies_up_to_date: false, }, - ], - id: 'zoom', - status: 'not_installed', + references: [], + coreMigrationVersion: '7.14.0', + updated_at: '2021-08-25T19:44:53.517Z', + version: 'WzczMTIsNF0=', + }, + categories: ['os_system', 'productivity'], }, { - name: 'zscaler', - title: 'Zscaler NSS', - version: '0.2.0', + name: 'exp_installed_update', + title: 'l. Experimental, Installed, Update', + version: '0.0.11', release: 'experimental', - description: 'Zscaler NSS Integration', + description: 'A package that is experimental, installed, with update', type: 'integration', - download: '/epr/zscaler/zscaler-0.2.0.zip', - path: '/package/zscaler/0.2.0', - icons: [ - { - src: '/img/logo.svg', - path: '/package/zscaler/0.2.0/img/logo.svg', - title: 'Zscaler NSS logo', - size: '32x32', - type: 'image/svg+xml', - }, - ], - policy_templates: [ - { - name: 'zia', - title: 'Zscaler NSS', - description: 'Collect Zscaler NSS logs from syslog or a file.', + download: '/epr/exp/installed', + path: '/package/exp/installed', + id: 'exp_installed_update', + status: 'installed', + savedObject: { + type: 'epm-packages', + id: 'exp_installed_update', + attributes: { + installed_kibana: [], + installed_es: [], + package_assets: [], + es_index_patterns: {}, + name: 'exp_installed_update', + version: '0.0.8', + internal: false, + removable: false, + install_version: '0.0.8', + install_status: 'installed', + install_started_at: '2021-08-25T19:44:37.078Z', + install_source: 'registry', + keep_policies_up_to_date: false, }, - ], - id: 'zscaler', - status: 'not_installed', + references: [], + coreMigrationVersion: '7.14.0', + updated_at: '2021-08-25T19:44:53.517Z', + version: 'WzczMTIsNF0=', + }, + categories: ['aws', 'cloud', 'elastic_stack'], }, ]; diff --git a/x-pack/plugins/fleet/storybook/context/fixtures/replacement_integrations.ts b/x-pack/plugins/fleet/storybook/context/fixtures/replacement_integrations.ts new file mode 100644 index 0000000000000..db3725ffe664c --- /dev/null +++ b/x-pack/plugins/fleet/storybook/context/fixtures/replacement_integrations.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CustomIntegration } from '../../../../../../src/plugins/custom_integrations/common'; + +export const integrations: CustomIntegration[] = [ + { + id: 'b.ga_beats', + categories: ['azure', 'cloud', 'config_management'], + description: 'Beats for a GA package that is not installed', + isBeta: false, + shipper: 'beats', + icons: [ + { + type: 'eui', + src: 'logoBeats', + }, + ], + title: 'b. GA, has Beats', + type: 'ui_link', + uiInternalPath: '/', + eprOverlap: 'ga_beats', + }, + { + id: 'f.beta_beats', + categories: ['azure', 'cloud', 'config_management'], + description: 'Beats for a beta package that is not installed', + isBeta: false, + shipper: 'beats', + icons: [ + { + type: 'eui', + src: 'logoBeats', + }, + ], + title: 'f. Beta, has Beats', + type: 'ui_link', + uiInternalPath: '/', + eprOverlap: 'beta_beats', + }, + { + id: 'j.exp_beats', + categories: ['azure', 'cloud', 'config_management'], + description: 'Beats for an experimental package that is not installed', + isBeta: false, + shipper: 'beats', + icons: [ + { + type: 'eui', + src: 'logoBeats', + }, + ], + title: 'j. Experimental, has Beats', + type: 'ui_link', + uiInternalPath: '/', + eprOverlap: 'exp_beats', + }, +]; diff --git a/x-pack/plugins/fleet/storybook/context/http.ts b/x-pack/plugins/fleet/storybook/context/http.ts index c52429c243ba9..3e515c075a595 100644 --- a/x-pack/plugins/fleet/storybook/context/http.ts +++ b/x-pack/plugins/fleet/storybook/context/http.ts @@ -27,6 +27,7 @@ export const getHttp = (basepath = BASE_PATH) => { serverBasePath: basepath, }, get: (async (path: string, options: HttpFetchOptions) => { + action('get')(path, options); // TODO: all of this needs revision, as it's far too clunky... but it works for now, // with the few paths we're supporting. if (path === '/api/fleet/agents/setup') { @@ -74,6 +75,11 @@ export const getHttp = (basepath = BASE_PATH) => { return await import('./fixtures/integration.okta'); } + if (path.startsWith('/api/fleet/check-permissions')) { + return { success: true }; + } + + action(path)('KP: UNSUPPORTED ROUTE'); return {}; }) as HttpHandler, } as unknown as HttpStart; diff --git a/x-pack/plugins/fleet/storybook/context/index.tsx b/x-pack/plugins/fleet/storybook/context/index.tsx index 6d563346e917d..e6c0726e755c2 100644 --- a/x-pack/plugins/fleet/storybook/context/index.tsx +++ b/x-pack/plugins/fleet/storybook/context/index.tsx @@ -28,6 +28,8 @@ import { getUiSettings } from './ui_settings'; import { getNotifications } from './notifications'; import { stubbedStartServices } from './stubs'; import { getDocLinks } from './doc_links'; +import { getCloud } from './cloud'; +import { getShare } from './share'; // TODO: clintandrewhall - this is not ideal, or complete. The root context of Fleet applications // requires full start contracts of its dependencies. As a result, we have to mock all of those contracts @@ -36,6 +38,7 @@ import { getDocLinks } from './doc_links'; // // Expect this to grow as components that are given Stories need access to mocked services. export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({ + storyContext, children: storyChildren, }) => { const basepath = ''; @@ -46,10 +49,12 @@ export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({ ...stubbedStartServices, application: getApplication(), chrome: getChrome(), + cloud: getCloud({ isCloudEnabled: storyContext?.args.isCloudEnabled }), + customIntegrations: { + ContextProvider: getStorybookContextProvider(), + }, docLinks: getDocLinks(), http: getHttp(), - notifications: getNotifications(), - uiSettings: getUiSettings(), i18n: { Context: function I18nContext({ children }) { return <I18nProvider>{children}</I18nProvider>; @@ -58,15 +63,18 @@ export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({ injectedMetadata: { getInjectedVar: () => null, }, - customIntegrations: { - ContextProvider: getStorybookContextProvider(), - }, + notifications: getNotifications(), + share: getShare(), + uiSettings: getUiSettings(), }; setHttpClient(startServices.http); setCustomIntegrations({ getAppendCustomIntegrations: async () => [], - getReplacementCustomIntegrations: async () => [], + getReplacementCustomIntegrations: async () => { + const { integrations } = await import('./fixtures/replacement_integrations'); + return integrations; + }, }); const config = { @@ -78,12 +86,20 @@ export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({ } as unknown as FleetConfigType; const extensions = {}; - const kibanaVersion = '1.2.3'; + const setHeaderActionMenu = () => {}; return ( <IntegrationsAppContext - {...{ kibanaVersion, basepath, config, history, startServices, extensions }} + {...{ + kibanaVersion, + basepath, + config, + history, + startServices, + extensions, + setHeaderActionMenu, + }} > {storyChildren} </IntegrationsAppContext> diff --git a/x-pack/plugins/fleet/storybook/context/share.ts b/x-pack/plugins/fleet/storybook/context/share.ts new file mode 100644 index 0000000000000..b6a8dfbcdcb67 --- /dev/null +++ b/x-pack/plugins/fleet/storybook/context/share.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 type { SharePluginStart } from 'src/plugins/share/public'; + +export const getShare = () => { + const share: SharePluginStart = { + url: { + locators: { + get: () => ({ + useUrl: () => 'https://locator.url', + }), + }, + }, + } as unknown as SharePluginStart; + + return share; +}; diff --git a/x-pack/plugins/fleet/storybook/context/stubs.tsx b/x-pack/plugins/fleet/storybook/context/stubs.tsx index a7db4bd8f68cd..f72b176bd8d7b 100644 --- a/x-pack/plugins/fleet/storybook/context/stubs.tsx +++ b/x-pack/plugins/fleet/storybook/context/stubs.tsx @@ -14,8 +14,7 @@ type Stubs = | 'fatalErrors' | 'navigation' | 'overlays' - | 'savedObjects' - | 'cloud'; + | 'savedObjects'; type StubbedStartServices = Pick<FleetStartServices, Stubs>; @@ -27,5 +26,4 @@ export const stubbedStartServices: StubbedStartServices = { navigation: {} as FleetStartServices['navigation'], overlays: {} as FleetStartServices['overlays'], savedObjects: {} as FleetStartServices['savedObjects'], - cloud: {} as FleetStartServices['cloud'], }; diff --git a/x-pack/plugins/fleet/storybook/decorator.tsx b/x-pack/plugins/fleet/storybook/decorator.tsx index 8e68249809574..93870809c94bb 100644 --- a/x-pack/plugins/fleet/storybook/decorator.tsx +++ b/x-pack/plugins/fleet/storybook/decorator.tsx @@ -11,5 +11,5 @@ import type { DecoratorFn } from '@storybook/react'; import { StorybookContext } from './context'; export const decorator: DecoratorFn = (story, storybook) => { - return <StorybookContext>{story()}</StorybookContext>; + return <StorybookContext storyContext={storybook}>{story()}</StorybookContext>; }; diff --git a/x-pack/plugins/graph/public/services/workspace/graph_client_workspace.d.ts b/x-pack/plugins/graph/public/services/workspace/graph_client_workspace.d.ts index b369ec6c5762c..18d08d8da31d8 100644 --- a/x-pack/plugins/graph/public/services/workspace/graph_client_workspace.d.ts +++ b/x-pack/plugins/graph/public/services/workspace/graph_client_workspace.d.ts @@ -5,6 +5,6 @@ * 2.0. */ -import { Workspace, WorkspaceOptions } from '../types'; +import { Workspace, WorkspaceOptions } from '../../types'; declare function createWorkspace(options: WorkspaceOptions): Workspace; diff --git a/x-pack/plugins/index_management/__jest__/components/index_table.test.js b/x-pack/plugins/index_management/__jest__/components/index_table.test.js index ba07db10d22d8..808c44ddecce0 100644 --- a/x-pack/plugins/index_management/__jest__/components/index_table.test.js +++ b/x-pack/plugins/index_management/__jest__/components/index_table.test.js @@ -88,7 +88,7 @@ const snapshot = (rendered) => { expect(rendered).toMatchSnapshot(); }; -const openMenuAndClickButton = (rendered, rowIndex, buttonIndex) => { +const openMenuAndClickButton = (rendered, rowIndex, buttonSelector) => { // Select a row. const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(rowIndex).simulate('change', { target: { checked: true } }); @@ -100,18 +100,18 @@ const openMenuAndClickButton = (rendered, rowIndex, buttonIndex) => { rendered.update(); // Click an action in the context menu. - const contextMenuButtons = findTestSubject(rendered, 'indexTableContextMenuButton'); - contextMenuButtons.at(buttonIndex).simulate('click'); + const contextMenuButton = findTestSubject(rendered, buttonSelector); + contextMenuButton.simulate('click'); rendered.update(); }; -const testEditor = (rendered, buttonIndex, rowIndex = 0) => { - openMenuAndClickButton(rendered, rowIndex, buttonIndex); +const testEditor = (rendered, buttonSelector, rowIndex = 0) => { + openMenuAndClickButton(rendered, rowIndex, buttonSelector); rendered.update(); snapshot(findTestSubject(rendered, 'detailPanelTabSelected').text()); }; -const testAction = (rendered, buttonIndex, rowIndex = 0) => { +const testAction = (rendered, buttonSelector, rowIndex = 0) => { // This is leaking some implementation details about how Redux works. Not sure exactly what's going on // but it looks like we're aware of how many Redux actions are dispatched in response to user interaction, // so we "time" our assertion based on how many Redux actions we observe. This is brittle because it @@ -127,7 +127,7 @@ const testAction = (rendered, buttonIndex, rowIndex = 0) => { dispatchedActionsCount++; }); - openMenuAndClickButton(rendered, rowIndex, buttonIndex); + openMenuAndClickButton(rendered, rowIndex, buttonSelector); // take snapshot of initial state. snapshot(status(rendered, rowIndex)); }; @@ -140,6 +140,11 @@ const namesText = (rendered) => { return names(rendered).map((button) => button.text()); }; +const getActionMenuButtons = (rendered) => { + return findTestSubject(rendered, 'indexContextMenu') + .find('button') + .map((span) => span.text()); +}; describe('index table', () => { beforeEach(() => { // Mock initialization of services @@ -232,7 +237,7 @@ describe('index table', () => { await runAllPromises(); rendered.update(); - let button = findTestSubject(rendered, 'indexTableContextMenuButton'); + let button = findTestSubject(rendered, 'indexActionsContextMenuButton'); expect(button.length).toEqual(0); const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); @@ -247,7 +252,7 @@ describe('index table', () => { await runAllPromises(); rendered.update(); - let button = findTestSubject(rendered, 'indexTableContextMenuButton'); + let button = findTestSubject(rendered, 'indexActionsContextMenuButton'); expect(button.length).toEqual(0); const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); @@ -353,7 +358,7 @@ describe('index table', () => { const actionButton = findTestSubject(rendered, 'indexActionsContextMenuButton'); actionButton.simulate('click'); rendered.update(); - snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); + snapshot(getActionMenuButtons(rendered)); }); test('should show the right context menu options when one index is selected and closed', async () => { @@ -367,7 +372,7 @@ describe('index table', () => { const actionButton = findTestSubject(rendered, 'indexActionsContextMenuButton'); actionButton.simulate('click'); rendered.update(); - snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); + snapshot(getActionMenuButtons(rendered)); }); test('should show the right context menu options when one open and one closed index is selected', async () => { @@ -382,7 +387,7 @@ describe('index table', () => { const actionButton = findTestSubject(rendered, 'indexActionsContextMenuButton'); actionButton.simulate('click'); rendered.update(); - snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); + snapshot(getActionMenuButtons(rendered)); }); test('should show the right context menu options when more than one open index is selected', async () => { @@ -397,7 +402,7 @@ describe('index table', () => { const actionButton = findTestSubject(rendered, 'indexActionsContextMenuButton'); actionButton.simulate('click'); rendered.update(); - snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); + snapshot(getActionMenuButtons(rendered)); }); test('should show the right context menu options when more than one closed index is selected', async () => { @@ -412,28 +417,28 @@ describe('index table', () => { const actionButton = findTestSubject(rendered, 'indexActionsContextMenuButton'); actionButton.simulate('click'); rendered.update(); - snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); + snapshot(getActionMenuButtons(rendered)); }); test('flush button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testAction(rendered, 8); + testAction(rendered, 'flushIndexMenuButton'); }); test('clear cache button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testAction(rendered, 7); + testAction(rendered, 'clearCacheIndexMenuButton'); }); test('refresh button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testAction(rendered, 6); + testAction(rendered, 'refreshIndexMenuButton'); }); test('force merge button works from context menu', async () => { @@ -442,7 +447,7 @@ describe('index table', () => { rendered.update(); const rowIndex = 0; - openMenuAndClickButton(rendered, rowIndex, 5); + openMenuAndClickButton(rendered, rowIndex, 'forcemergeIndexMenuButton'); snapshot(status(rendered, rowIndex)); expect(rendered.find('.euiModal').length).toBe(1); @@ -478,7 +483,7 @@ describe('index table', () => { JSON.stringify(modifiedIndices), ]); - testAction(rendered, 4); + testAction(rendered, 'closeIndexMenuButton'); }); test('open index button works from context menu', async () => { @@ -499,34 +504,34 @@ describe('index table', () => { JSON.stringify(modifiedIndices), ]); - testAction(rendered, 3, 1); + testAction(rendered, 'openIndexMenuButton', 1); }); test('show settings button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testEditor(rendered, 0); + testEditor(rendered, 'showSettingsIndexMenuButton'); }); test('show mappings button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testEditor(rendered, 1); + testEditor(rendered, 'showMappingsIndexMenuButton'); }); test('show stats button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testEditor(rendered, 2); + testEditor(rendered, 'showStatsIndexMenuButton'); }); test('edit index button works from context menu', async () => { const rendered = mountWithIntl(component); await runAllPromises(); rendered.update(); - testEditor(rendered, 3); + testEditor(rendered, 'editIndexMenuButton'); }); }); diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js index a97d5b11161b1..c5bd62feff826 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js @@ -75,6 +75,7 @@ export class IndexActionsContextMenu extends Component { const items = []; if (!detailPanel && selectedIndexCount === 1) { items.push({ + 'data-test-subj': 'showSettingsIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.showIndexSettingsLabel', { defaultMessage: 'Show {selectedIndexCount, plural, one {index} other {indices} } settings', @@ -85,6 +86,7 @@ export class IndexActionsContextMenu extends Component { }, }); items.push({ + 'data-test-subj': 'showMappingsIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.showIndexMappingLabel', { defaultMessage: 'Show {selectedIndexCount, plural, one {index} other {indices} } mapping', values: { selectedIndexCount }, @@ -95,6 +97,7 @@ export class IndexActionsContextMenu extends Component { }); if (allOpen) { items.push({ + 'data-test-subj': 'showStatsIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.showIndexStatsLabel', { defaultMessage: 'Show {selectedIndexCount, plural, one {index} other {indices} } stats', values: { selectedIndexCount }, @@ -105,6 +108,7 @@ export class IndexActionsContextMenu extends Component { }); } items.push({ + 'data-test-subj': 'editIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.editIndexSettingsLabel', { defaultMessage: 'Edit {selectedIndexCount, plural, one {index} other {indices} } settings', @@ -117,6 +121,7 @@ export class IndexActionsContextMenu extends Component { } if (allOpen) { items.push({ + 'data-test-subj': 'closeIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.closeIndexLabel', { defaultMessage: 'Close {selectedIndexCount, plural, one {index} other {indices} }', values: { selectedIndexCount }, @@ -131,6 +136,7 @@ export class IndexActionsContextMenu extends Component { }, }); items.push({ + 'data-test-subj': 'forcemergeIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.forceMergeIndexLabel', { defaultMessage: 'Force merge {selectedIndexCount, plural, one {index} other {indices} }', values: { selectedIndexCount }, @@ -141,6 +147,7 @@ export class IndexActionsContextMenu extends Component { }, }); items.push({ + 'data-test-subj': 'refreshIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.refreshIndexLabel', { defaultMessage: 'Refresh {selectedIndexCount, plural, one {index} other {indices} }', values: { selectedIndexCount }, @@ -150,6 +157,7 @@ export class IndexActionsContextMenu extends Component { }, }); items.push({ + 'data-test-subj': 'clearCacheIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.clearIndexCacheLabel', { defaultMessage: 'Clear {selectedIndexCount, plural, one {index} other {indices} } cache', values: { selectedIndexCount }, @@ -159,6 +167,7 @@ export class IndexActionsContextMenu extends Component { }, }); items.push({ + 'data-test-subj': 'flushIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.flushIndexLabel', { defaultMessage: 'Flush {selectedIndexCount, plural, one {index} other {indices} }', values: { selectedIndexCount }, @@ -191,6 +200,7 @@ export class IndexActionsContextMenu extends Component { } } else { items.push({ + 'data-test-subj': 'openIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.openIndexLabel', { defaultMessage: 'Open {selectedIndexCount, plural, one {index} other {indices} }', values: { selectedIndexCount }, @@ -239,9 +249,6 @@ export class IndexActionsContextMenu extends Component { } } }); - items.forEach((item) => { - item['data-test-subj'] = 'indexTableContextMenuButton'; - }); const panelTree = { id: 0, title: i18n.translate('xpack.idxMgmt.indexActionsMenu.panelTitle', { @@ -732,7 +739,11 @@ export class IndexActionsContextMenu extends Component { anchorPosition={anchorPosition} repositionOnScroll > - <EuiContextMenu initialPanelId={0} panels={panels} /> + <EuiContextMenu + initialPanelId={0} + panels={panels} + data-test-subj="indexContextMenu" + /> </EuiPopover> </div> ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/filter_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/filter_bar.tsx index f29f87191bc13..deef63892ac95 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/filter_bar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/filter_bar.tsx @@ -11,13 +11,13 @@ import React from 'react'; import { WaffleTimeControls } from './waffle/waffle_time_controls'; import { SearchBar } from './search_bar'; -export const FilterBar = () => ( +export const FilterBar = ({ interval }: { interval: string }) => ( <EuiFlexGroup justifyContent="spaceBetween" gutterSize="m" style={{ flexGrow: 0 }}> <EuiFlexItem> <SearchBar /> </EuiFlexItem> <EuiFlexItem grow={false}> - <WaffleTimeControls /> + <WaffleTimeControls interval={interval} /> </EuiFlexItem> </EuiFlexGroup> ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx index f241f5d118147..de0a56c5be73d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx @@ -9,13 +9,12 @@ import React, { useCallback, useEffect, useState } from 'react'; import useInterval from 'react-use/lib/useInterval'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { SnapshotNode } from '../../../../../common/http_api'; import { SavedView } from '../../../../containers/saved_view/saved_view'; import { AutoSizer } from '../../../../components/auto_sizer'; -import { convertIntervalToString } from '../../../../utils/convert_interval_to_string'; import { NodesOverview } from './nodes_overview'; import { calculateBoundsFromNodes } from '../lib/calculate_bounds_from_nodes'; import { PageContent } from '../../../../components/page'; -import { useSnapshot } from '../hooks/use_snaphot'; import { useWaffleTimeContext } from '../hooks/use_waffle_time'; import { useWaffleFiltersContext } from '../hooks/use_waffle_filters'; import { DEFAULT_LEGEND, useWaffleOptionsContext } from '../hooks/use_waffle_options'; @@ -24,30 +23,30 @@ import { InfraFormatterType } from '../../../../lib/lib'; import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common'; import { Toolbar } from './toolbars/toolbar'; import { ViewSwitcher } from './waffle/view_switcher'; -import { IntervalLabel } from './waffle/interval_label'; import { createInventoryMetricFormatter } from '../lib/create_inventory_metric_formatter'; import { createLegend } from '../lib/create_legend'; import { useWaffleViewState } from '../hooks/use_waffle_view_state'; import { BottomDrawer } from './bottom_drawer'; import { Legend } from './waffle/legend'; +interface Props { + shouldLoadDefault: boolean; + currentView: SavedView<any> | null; + reload: () => Promise<any>; + interval: string; + nodes: SnapshotNode[]; + loading: boolean; +} + export const Layout = React.memo( - ({ - shouldLoadDefault, - currentView, - }: { - shouldLoadDefault: boolean; - currentView: SavedView<any> | null; - }) => { + ({ shouldLoadDefault, currentView, reload, interval, nodes, loading }: Props) => { const [showLoading, setShowLoading] = useState(true); - const { sourceId, source } = useSourceContext(); + const { source } = useSourceContext(); const { metric, groupBy, sort, nodeType, - accountId, - region, changeView, view, autoBounds, @@ -55,19 +54,7 @@ export const Layout = React.memo( legend, } = useWaffleOptionsContext(); const { currentTime, jumpToTime, isAutoReloading } = useWaffleTimeContext(); - const { filterQueryAsJson, applyFilterQuery } = useWaffleFiltersContext(); - const { loading, nodes, reload, interval } = useSnapshot( - filterQueryAsJson, - [metric], - groupBy, - nodeType, - sourceId, - currentTime, - accountId, - region, - false - ); - + const { applyFilterQuery } = useWaffleFiltersContext(); const legendPalette = legend?.palette ?? DEFAULT_LEGEND.palette; const legendSteps = legend?.steps ?? DEFAULT_LEGEND.steps; const legendReverseColors = legend?.reverseColors ?? DEFAULT_LEGEND.reverseColors; @@ -91,7 +78,6 @@ export const Layout = React.memo( isAutoReloading ? 5000 : null ); - const intervalAsString = convertIntervalToString(interval); const dataBounds = calculateBoundsFromNodes(nodes); const bounds = autoBounds ? dataBounds : boundsOverride; /* eslint-disable-next-line react-hooks/exhaustive-deps */ @@ -151,9 +137,6 @@ export const Layout = React.memo( gutterSize="m" > <Toolbar nodeType={nodeType} currentTime={currentTime} /> - <EuiFlexItem grow={false} className="eui-hideFor--s eui-hideFor--xs"> - <IntervalLabel intervalAsString={intervalAsString} /> - </EuiFlexItem> <EuiFlexItem grow={false}> <ViewSwitcher view={view} onChange={changeView} /> </EuiFlexItem> diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout_view.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout_view.tsx index 1e66fe22ac45e..af9c9ab5e2b30 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout_view.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout_view.tsx @@ -6,10 +6,18 @@ */ import React from 'react'; +import { SnapshotNode } from '../../../../../common/http_api'; import { useSavedViewContext } from '../../../../containers/saved_view/saved_view'; import { Layout } from './layout'; -export const LayoutView = () => { +interface Props { + reload: () => Promise<any>; + interval: string; + nodes: SnapshotNode[]; + loading: boolean; +} + +export const LayoutView = (props: Props) => { const { shouldLoadDefault, currentView } = useSavedViewContext(); - return <Layout shouldLoadDefault={shouldLoadDefault} currentView={currentView} />; + return <Layout shouldLoadDefault={shouldLoadDefault} currentView={currentView} {...props} />; }; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/snapshot_container.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/snapshot_container.tsx new file mode 100644 index 0000000000000..e64e79c99f6fc --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/snapshot_container.tsx @@ -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 React from 'react'; +import { useSourceContext } from '../../../../containers/metrics_source'; +import { SnapshotNode } from '../../../../../common/http_api'; +import { useSnapshot } from '../hooks/use_snaphot'; +import { useWaffleFiltersContext } from '../hooks/use_waffle_filters'; +import { useWaffleOptionsContext } from '../hooks/use_waffle_options'; +import { useWaffleTimeContext } from '../hooks/use_waffle_time'; + +interface RenderProps { + reload: () => Promise<any>; + interval: string; + nodes: SnapshotNode[]; + loading: boolean; +} + +interface Props { + render: React.FC<RenderProps>; +} +export const SnapshotContainer = ({ render }: Props) => { + const { sourceId } = useSourceContext(); + const { metric, groupBy, nodeType, accountId, region } = useWaffleOptionsContext(); + const { currentTime } = useWaffleTimeContext(); + const { filterQueryAsJson } = useWaffleFiltersContext(); + const { loading, nodes, reload, interval } = useSnapshot( + filterQueryAsJson, + [metric], + groupBy, + nodeType, + sourceId, + currentTime, + accountId, + region, + false + ); + return render({ loading, nodes, reload, interval }); +}; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx index 39150a98c2e89..7ac618987b422 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx @@ -5,22 +5,25 @@ * 2.0. */ -import { EuiButton, EuiDatePicker, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButton, EuiDatePicker, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import moment, { Moment } from 'moment'; import React, { useCallback } from 'react'; +import { convertIntervalToString } from '../../../../../utils/convert_interval_to_string'; import { withTheme, EuiTheme } from '../../../../../../../../../src/plugins/kibana_react/common'; import { useWaffleTimeContext } from '../../hooks/use_waffle_time'; interface Props { theme: EuiTheme | undefined; + interval: string; } -export const WaffleTimeControls = withTheme(({ theme }: Props) => { +export const WaffleTimeControls = withTheme(({ interval }: Props) => { const { currentTime, isAutoReloading, startAutoReload, stopAutoReload, jumpToTime } = useWaffleTimeContext(); const currentMoment = moment(currentTime); + const intervalAsString = convertIntervalToString(interval); const liveStreamingButton = isAutoReloading ? ( <EuiButton color="primary" iconSide="left" iconType="pause" onClick={stopAutoReload}> @@ -50,18 +53,25 @@ export const WaffleTimeControls = withTheme(({ theme }: Props) => { return ( <EuiFlexGroup gutterSize="m"> <EuiFlexItem grow={false} data-test-subj="waffleDatePicker"> - <EuiDatePicker - dateFormat="L LTS" - disabled={isAutoReloading} - injectTimes={currentMoment ? [currentMoment] : []} - isLoading={isAutoReloading} - onChange={handleChangeDate} - popperPlacement="top-end" - selected={currentMoment} - shouldCloseOnSelect - showTimeSelect - timeFormat="LT" - /> + <EuiToolTip + content={`Last ${intervalAsString} of data for the selected time`} + delay="long" + display="inlineBlock" + position="top" + > + <EuiDatePicker + dateFormat="L LTS" + disabled={isAutoReloading} + injectTimes={currentMoment ? [currentMoment] : []} + isLoading={isAutoReloading} + onChange={handleChangeDate} + popperPlacement="top-end" + selected={currentMoment} + shouldCloseOnSelect + showTimeSelect + timeFormat="LT" + /> + </EuiToolTip> </EuiFlexItem> <EuiFlexItem grow={false}>{liveStreamingButton}</EuiFlexItem> </EuiFlexGroup> diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx index 67e39a11c12e7..87765088d6343 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx @@ -26,6 +26,7 @@ import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common' import { APP_WRAPPER_CLASS } from '../../../../../../../src/core/public'; import { inventoryTitle } from '../../../translations'; import { SavedViews } from './components/saved_views'; +import { SnapshotContainer } from './components/snapshot_container'; export const SnapshotPage = () => { const { @@ -78,8 +79,19 @@ export const SnapshotPage = () => { paddingSize: 'none', }} > - <FilterBar /> - <LayoutView /> + <SnapshotContainer + render={({ loading, nodes, reload, interval }) => ( + <> + <FilterBar interval={interval} /> + <LayoutView + loading={loading} + nodes={nodes} + reload={reload} + interval={interval} + /> + </> + )} + /> </MetricsPageTemplate> </SavedViewProvider> </InventoryPageWrapper> diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx index 2f1c00bc5cca0..8286ab492f14d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx @@ -731,9 +731,9 @@ export function DimensionEditor(props: DimensionEditorProps) { /> {TabContent} - {!isFullscreen && !currentFieldIsInvalid && temporaryState === 'none' && ( + {!isFullscreen && !currentFieldIsInvalid && ( <div className="lnsIndexPatternDimensionEditor__section lnsIndexPatternDimensionEditor__section--padded"> - {!incompleteInfo && selectedColumn && ( + {!incompleteInfo && selectedColumn && temporaryState === 'none' && ( <LabelInput value={selectedColumn.label} onChange={(value) => { @@ -756,7 +756,7 @@ export function DimensionEditor(props: DimensionEditorProps) { /> )} - {!isFullscreen && !incompleteInfo && !hideGrouping && ( + {!isFullscreen && !incompleteInfo && !hideGrouping && temporaryState === 'none' && ( <BucketNestingEditor layer={state.layers[props.layerId]} columnId={props.columnId} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts index ef1de43ad06ed..77a2b334a9e20 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts @@ -1139,6 +1139,122 @@ describe('state_helpers', () => { }).columns.col1 ).toEqual(expect.objectContaining({ label: 'Average of bytes' })); }); + + it('should carry over a custom label when transitioning to a managed reference', () => { + expect( + replaceColumn({ + layer: { + indexPatternId: '1', + columnOrder: ['col1', 'col2'], + columns: { + col1: { + label: 'MY CUSTOM LABEL', + customLabel: true, + dataType: 'string', + isBucketed: true, + operationType: 'terms', + sourceField: 'source', + params: { + orderBy: { type: 'alphabetical' }, + orderDirection: 'asc', + size: 5, + }, + }, + }, + }, + indexPattern, + columnId: 'col1', + op: 'formula', + field: indexPattern.fields[2], // bytes field + visualizationGroups: [], + shouldResetLabel: undefined, + }).columns.col1 + ).toEqual(expect.objectContaining({ label: 'MY CUSTOM LABEL' })); + }); + + it('should overwrite the current label when transitioning to a managed reference operation when not custom', () => { + expect( + replaceColumn({ + layer: { + indexPatternId: '1', + columnOrder: ['col1', 'col2'], + columns: { + col1: { + label: 'Average of bytes', + dataType: 'number', + isBucketed: false, + operationType: 'average', + sourceField: 'bytes', + }, + }, + }, + indexPattern, + columnId: 'col1', + op: 'formula', + field: indexPattern.fields[2], // bytes field + visualizationGroups: [], + shouldResetLabel: undefined, + }).columns.col1 + ).toEqual(expect.objectContaining({ label: 'average(bytes)' })); + }); + + it('should carry over a custom label when transitioning from a managed reference', () => { + expect( + replaceColumn({ + layer: { + indexPatternId: '1', + columnOrder: ['col1', 'col2'], + columns: { + col1: { + label: 'MY CUSTOM LABEL', + customLabel: true, + dataType: 'number', + operationType: 'formula', + isBucketed: false, + scale: 'ratio', + params: { isFormulaBroken: false, formula: 'average(bytes)' }, + references: [], + }, + }, + }, + indexPattern, + columnId: 'col1', + op: 'average', + field: indexPattern.fields[2], // bytes field + visualizationGroups: [], + shouldResetLabel: undefined, + }).columns.col1 + ).toEqual(expect.objectContaining({ label: 'MY CUSTOM LABEL' })); + }); + + it('should not carry over the managed reference default label to the new operation', () => { + expect( + replaceColumn({ + layer: { + indexPatternId: '1', + columnOrder: ['col1', 'col2'], + columns: { + col1: { + label: 'average(bytes)', + customLabel: true, + dataType: 'number', + operationType: 'formula', + isBucketed: false, + scale: 'ratio', + params: { isFormulaBroken: false, formula: 'average(bytes)' }, + references: [], + }, + }, + }, + indexPattern, + columnId: 'col1', + op: 'average', + field: indexPattern.fields[2], // bytes field + visualizationGroups: [], + shouldResetLabel: undefined, + }).columns.col1 + ).toEqual(expect.objectContaining({ label: 'Average of bytes' })); + }); }); it('should execute adjustments for other columns', () => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index baacc7bb64d16..b3b98e5054aa6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -417,6 +417,17 @@ export function replaceColumn({ field, visualizationGroups, }); + + // if the formula label is not the default one, propagate it to the new operation + if ( + !shouldResetLabel && + previousColumn.customLabel && + previousColumn.label !== + previousDefinition.getDefaultLabel(previousColumn, indexPattern, tempLayer.columns) + ) { + hypotheticalLayer.columns[columnId].customLabel = true; + hypotheticalLayer.columns[columnId].label = previousColumn.label; + } if (hypotheticalLayer.incompleteColumns && hypotheticalLayer.incompleteColumns[columnId]) { return { ...layer, @@ -500,13 +511,10 @@ export function replaceColumn({ // TODO: Refactor all this to be more generic and know less about Formula // if managed it has to look at the full picture to have a seamless transition if (operationDefinition.input === 'managedReference') { - const newColumn = copyCustomLabel( - operationDefinition.buildColumn( - { ...baseOptions, layer: tempLayer }, - previousColumn.params, - operationDefinitionMap - ), - previousColumn + const newColumn = operationDefinition.buildColumn( + { ...baseOptions, layer: tempLayer }, + previousColumn.params, + operationDefinitionMap ) as FormulaIndexPatternColumn; // now remove the previous references @@ -535,6 +543,17 @@ export function replaceColumn({ newLayer = basicLayer; } + // when coming to Formula keep the custom label + const regeneratedColumn = newLayer.columns[columnId]; + if ( + !shouldResetLabel && + regeneratedColumn.operationType !== previousColumn.operationType && + previousColumn.customLabel + ) { + regeneratedColumn.customLabel = true; + regeneratedColumn.label = previousColumn.label; + } + return updateDefaultLabels( { ...tempLayer, diff --git a/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx index a3ac5b5837772..db70a7c8508e5 100644 --- a/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx @@ -90,7 +90,9 @@ describe('metric_expression', () => { reportDescription="Fancy chart description" reportTitle="My fanci metric chart" > - <AutoScale> + <AutoScale + key="3" + > <div data-test-subj="lns_metric_value" style={ @@ -135,7 +137,9 @@ describe('metric_expression', () => { reportDescription="Fancy chart description" reportTitle="My fanci metric chart" > - <AutoScale> + <AutoScale + key="last" + > <div data-test-subj="lns_metric_value" style={ @@ -179,7 +183,9 @@ describe('metric_expression', () => { reportDescription="" reportTitle="" > - <AutoScale> + <AutoScale + key="3" + > <div data-test-subj="lns_metric_value" style={ @@ -223,7 +229,9 @@ describe('metric_expression', () => { reportDescription="" reportTitle="" > - <AutoScale> + <AutoScale + key="3" + > <div data-test-subj="lns_metric_value" style={ @@ -309,7 +317,9 @@ describe('metric_expression', () => { reportDescription="" reportTitle="" > - <AutoScale> + <AutoScale + key="0" + > <div data-test-subj="lns_metric_value" style={ diff --git a/x-pack/plugins/lens/public/metric_visualization/expression.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.tsx index 8838e6df777c9..5b29a1898b560 100644 --- a/x-pack/plugins/lens/public/metric_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/expression.tsx @@ -89,7 +89,7 @@ export function MetricChart({ reportDescription={description} className="lnsMetricExpression__container" > - <AutoScale> + <AutoScale key={value}> <div data-test-subj="lns_metric_value" style={{ fontSize: '60pt', fontWeight: 600 }}> {value} </div> diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 87462e71f3cf6..7aee537ebbedd 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -67,6 +67,7 @@ import { getThresholdRequiredPaddings, ThresholdAnnotations, } from './expression_thresholds'; +import { computeOverallDataDomain } from './threshold_helpers'; declare global { interface Window { @@ -250,6 +251,10 @@ export function XYChart({ const chartBaseTheme = chartsThemeService.useChartsBaseTheme(); const darkMode = chartsThemeService.useDarkMode(); const filteredLayers = getFilteredLayers(layers, data); + const layersById = filteredLayers.reduce((memo, layer) => { + memo[layer.layerId] = layer; + return memo; + }, {} as Record<string, LayerArgs>); const handleCursorUpdate = useActiveCursor(chartsActiveCursorService, chartRef, { datatables: Object.values(data.tables), @@ -386,7 +391,7 @@ export function XYChart({ const extent = axis.groupId === 'left' ? yLeftExtent : yRightExtent; const hasBarOrArea = Boolean( axis.series.some((series) => { - const seriesType = filteredLayers.find((l) => l.layerId === series.layer)?.seriesType; + const seriesType = layersById[series.layer]?.seriesType; return seriesType?.includes('bar') || seriesType?.includes('area'); }) ); @@ -406,20 +411,15 @@ export function XYChart({ ); if (!fit && axisHasThreshold) { // Remove this once the chart will support automatic annotation fit for other type of charts - for (const series of axis.series) { - const table = data.tables[series.layer]; - for (const row of table.rows) { - for (const column of table.columns) { - if (column.id === series.accessor) { - const value = row[column.id]; - if (typeof value === 'number') { - // keep the 0 in view - max = Math.max(value, max || 0, 0); - min = Math.min(value, min || 0, 0); - } - } - } - } + const { min: computedMin, max: computedMax } = computeOverallDataDomain( + filteredLayers, + axis.series.map(({ accessor }) => accessor), + data.tables + ); + + if (computedMin != null && computedMax != null) { + max = Math.max(computedMax, max || 0); + min = Math.min(computedMin, min || 0); } for (const { layerId, yConfig } of thresholdLayers) { const table = data.tables[layerId]; diff --git a/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts b/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts index 4edf7fdf5e512..14a82011cb526 100644 --- a/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts +++ b/x-pack/plugins/lens/public/xy_visualization/state_helpers.ts @@ -26,6 +26,10 @@ export function isPercentageSeries(seriesType: SeriesType) { ); } +export function isStackedChart(seriesType: SeriesType) { + return seriesType.includes('stacked'); +} + export function isHorizontalChart(layers: Array<{ seriesType: SeriesType }>) { return layers.every((l) => isHorizontalSeries(l.seriesType)); } diff --git a/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.test.ts b/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.test.ts new file mode 100644 index 0000000000000..d7286de0316d6 --- /dev/null +++ b/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.test.ts @@ -0,0 +1,569 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { XYLayerConfig } from '../../common/expressions'; +import { FramePublicAPI } from '../types'; +import { computeOverallDataDomain, getStaticValue } from './threshold_helpers'; + +function getActiveData(json: Array<{ id: string; rows: Array<Record<string, number | null>> }>) { + return json.reduce((memo, { id, rows }) => { + const columns = Object.keys(rows[0]).map((columnId) => ({ + id: columnId, + name: columnId, + meta: { type: 'number' as const }, + })); + memo[id] = { + type: 'datatable' as const, + columns, + rows, + }; + return memo; + }, {} as NonNullable<FramePublicAPI['activeData']>); +} + +describe('threshold helpers', () => { + describe('getStaticValue', () => { + const hasDateHistogram = () => false; + const hasAllNumberHistogram = () => true; + + it('should return fallback value on missing data', () => { + expect(getStaticValue([], 'x', {}, hasAllNumberHistogram)).toBe(100); + }); + + it('should return fallback value on no-configuration/missing hit on current data', () => { + // no-config: missing layer + expect( + getStaticValue( + [], + 'x', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(100); + // accessor id has no hit in data + expect( + getStaticValue( + [{ layerId: 'id-a', seriesType: 'area' } as XYLayerConfig], // missing xAccessor for groupId == x + 'x', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(100); + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['d'], + } as XYLayerConfig, + ], // missing hit of accessor "d" in data + 'yLeft', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(100); + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a'], + } as XYLayerConfig, + ], // missing yConfig fallbacks to left axis, but the requested group is yRight + 'yRight', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(100); + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a'], + } as XYLayerConfig, + ], // same as above with x groupId + 'x', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(100); + }); + + it('should work for no yConfig defined and fallback to left axis', () => { + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a'], + } as XYLayerConfig, + ], + 'yLeft', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(75); // 3/4 of "a" only + }); + + it('should extract axis side from yConfig', () => { + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a'], + yConfig: [{ forAccessor: 'a', axisMode: 'right' }], + } as XYLayerConfig, + ], + 'yRight', + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(75); // 3/4 of "a" only + }); + + it('should correctly distribute axis on left and right with different formatters when in auto', () => { + const tables = getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 200, c: 100 }) }, + ]); + tables['id-a'].columns[0].meta.params = { id: 'number' }; // a: number formatter + tables['id-a'].columns[1].meta.params = { id: 'percent' }; // b: percent formatter + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a', 'b'], + } as XYLayerConfig, + ], + 'yLeft', + { activeData: tables }, + hasAllNumberHistogram + ) + ).toBe(75); // 3/4 of "a" only + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a', 'b'], + } as XYLayerConfig, + ], + 'yRight', + { activeData: tables }, + hasAllNumberHistogram + ) + ).toBe(150); // 3/4 of "b" only + }); + + it('should ignore hasHistogram for left or right axis', () => { + const tables = getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 200, c: 100 }) }, + ]); + tables['id-a'].columns[0].meta.params = { id: 'number' }; // a: number formatter + tables['id-a'].columns[1].meta.params = { id: 'percent' }; // b: percent formatter + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a', 'b'], + } as XYLayerConfig, + ], + 'yLeft', + { activeData: tables }, + hasDateHistogram + ) + ).toBe(75); // 3/4 of "a" only + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + accessors: ['a', 'b'], + } as XYLayerConfig, + ], + 'yRight', + { activeData: tables }, + hasDateHistogram + ) + ).toBe(150); // 3/4 of "b" only + }); + + it('should early exit for x group if a date histogram is detected', () => { + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + xAccessor: 'a', + accessors: [], + } as XYLayerConfig, + ], + 'x', // this is influenced by the callback + { + activeData: getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + ]), + }, + hasDateHistogram + ) + ).toBe(100); + }); + + it('should not force zero-based interval for x group', () => { + expect( + getStaticValue( + [ + { + layerId: 'id-a', + seriesType: 'area', + layerType: 'data', + xAccessor: 'a', + accessors: [], + } as XYLayerConfig, + ], + 'x', + { + activeData: getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ a: i % 2 ? 33 : 50 })), + }, + ]), + }, + hasAllNumberHistogram + ) + ).toBe(45.75); // 33 (min) + (50 - 33) * 3/4 + }); + }); + + describe('computeOverallDataDomain', () => { + it('should compute the correct value for a single layer with stacked series', () => { + for (const seriesType of ['bar_stacked', 'bar_horizontal_stacked', 'area_stacked']) + expect( + computeOverallDataDomain( + [{ layerId: 'id-a', seriesType, accessors: ['a', 'b', 'c'] } as XYLayerConfig], + ['a', 'b', 'c'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ + a: i === 0 ? 25 : null, + b: i === 1 ? 50 : null, + c: i === 2 ? 75 : null, + })), + }, + ]) + ) + ).toEqual({ min: 0, max: 150 }); // there's just one series with 150, so the lowerbound fallbacks to 0 + }); + + it('should work for percentage series', () => { + for (const seriesType of [ + 'bar_percentage_stacked', + 'bar_horizontal_percentage_stacked', + 'area_percentage_stacked', + ]) + expect( + computeOverallDataDomain( + [{ layerId: 'id-a', seriesType, accessors: ['a', 'b', 'c'] } as XYLayerConfig], + ['a', 'b', 'c'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ + a: i === 0 ? 0.25 : null, + b: i === 1 ? 0.25 : null, + c: i === 2 ? 0.25 : null, + })), + }, + ]) + ) + ).toEqual({ min: 0, max: 0.75 }); + }); + + it('should compute the correct value for multiple layers with stacked series', () => { + for (const seriesType of ['bar_stacked', 'bar_horizontal_stacked', 'area_stacked']) { + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType, accessors: ['a', 'b', 'c'] }, + { layerId: 'id-b', seriesType, accessors: ['d', 'e', 'f'] }, + ] as XYLayerConfig[], + ['a', 'b', 'c', 'd', 'e', 'f'], + getActiveData([ + { id: 'id-a', rows: [{ a: 25, b: 100, c: 100 }] }, + { id: 'id-b', rows: [{ d: 50, e: 50, f: 50 }] }, + ]) + ) + ).toEqual({ min: 0, max: 375 }); + // same as before but spread on 3 rows with nulls + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType, accessors: ['a', 'b', 'c'] }, + { layerId: 'id-b', seriesType, accessors: ['d', 'e', 'f'] }, + ] as XYLayerConfig[], + ['a', 'b', 'c', 'd', 'e', 'f'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ + a: i === 0 ? 25 : null, + b: i === 1 ? 100 : null, + c: i === 2 ? 100 : null, + })), + }, + { + id: 'id-b', + rows: Array(3) + .fill(1) + .map((_, i) => ({ + d: i === 0 ? 50 : null, + e: i === 1 ? 50 : null, + f: i === 2 ? 50 : null, + })), + }, + ]) + ) + ).toEqual({ min: 0, max: 375 }); + } + }); + + it('should compute the correct value for multiple layers with non-stacked series', () => { + for (const seriesType of ['bar', 'bar_horizontal', 'line', 'area']) + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType, accessors: ['a', 'b', 'c'] }, + { layerId: 'id-b', seriesType, accessors: ['d', 'e', 'f'] }, + ] as XYLayerConfig[], + ['a', 'b', 'c', 'd', 'e', 'f'], + getActiveData([ + { id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }, + { id: 'id-b', rows: Array(3).fill({ d: 50, e: 50, f: 50 }) }, + ]) + ) + ).toEqual({ min: 50, max: 100 }); + }); + + it('should compute the correct value for mixed series (stacked + non-stacked)', () => { + for (const nonStackedSeries of ['bar', 'bar_horizontal', 'line', 'area']) { + for (const stackedSeries of ['bar_stacked', 'bar_horizontal_stacked', 'area_stacked']) { + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType: nonStackedSeries, accessors: ['a', 'b', 'c'] }, + { layerId: 'id-b', seriesType: stackedSeries, accessors: ['d', 'e', 'f'] }, + ] as XYLayerConfig[], + ['a', 'b', 'c', 'd', 'e', 'f'], + getActiveData([ + { id: 'id-a', rows: [{ a: 100, b: 100, c: 100 }] }, + { id: 'id-b', rows: [{ d: 50, e: 50, f: 50 }] }, + ]) + ) + ).toEqual({ + min: 0, // min is 0 as there is at least one stacked series + max: 150, // max is id-b layer accessor sum + }); + } + } + }); + + it('should compute the correct value for a histogram stacked chart', () => { + for (const seriesType of ['bar_stacked', 'bar_horizontal_stacked', 'area_stacked']) + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType, xAccessor: 'c', accessors: ['a', 'b'] }, + { layerId: 'id-b', seriesType, xAccessor: 'f', accessors: ['d', 'e'] }, + ] as XYLayerConfig[], + ['a', 'b', 'd', 'e'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ a: 50 * i, b: 100 * i, c: i })), + }, + { + id: 'id-b', + rows: Array(3) + .fill(1) + .map((_, i) => ({ d: 25 * (i + 1), e: i % 2 ? 100 : null, f: i })), + }, + ]) + ) + ).toEqual({ min: 0, max: 375 }); + }); + + it('should compute the correct value for a histogram non-stacked chart', () => { + for (const seriesType of ['bar', 'bar_horizontal', 'line', 'area']) + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType, xAccessor: 'c', accessors: ['a', 'b'] }, + { layerId: 'id-b', seriesType, xAccessor: 'f', accessors: ['d', 'e'] }, + ] as XYLayerConfig[], + ['a', 'b', 'd', 'e'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ a: 50 * i, b: 100 * i, c: i })), + }, + { + id: 'id-b', + rows: Array(3) + .fill(1) + .map((_, i) => ({ d: 25 * (i + 1), e: i % 2 ? 100 : null, f: i })), + }, + ]) + ) + ).toEqual({ min: 0, max: 200 }); + }); + + it('should compute the result taking into consideration negative-based intervals too', () => { + // stacked + expect( + computeOverallDataDomain( + [ + { + layerId: 'id-a', + seriesType: 'area_stacked', + accessors: ['a', 'b', 'c'], + } as XYLayerConfig, + ], + ['a', 'b', 'c'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ + a: i === 0 ? -100 : null, + b: i === 1 ? 200 : null, + c: i === 2 ? 100 : null, + })), + }, + ]) + ) + ).toEqual({ min: 0, max: 200 }); // it is stacked, so max is the sum and 0 is the fallback + expect( + computeOverallDataDomain( + [{ layerId: 'id-a', seriesType: 'area', accessors: ['a', 'b', 'c'] } as XYLayerConfig], + ['a', 'b', 'c'], + getActiveData([ + { + id: 'id-a', + rows: Array(3) + .fill(1) + .map((_, i) => ({ + a: i === 0 ? -100 : null, + b: i === 1 ? 200 : null, + c: i === 2 ? 100 : null, + })), + }, + ]) + ) + ).toEqual({ min: -100, max: 200 }); + }); + + it('should return no result if no layers or accessors are passed', () => { + expect( + computeOverallDataDomain( + [], + ['a', 'b', 'c'], + getActiveData([{ id: 'id-a', rows: Array(3).fill({ a: 100, b: 100, c: 100 }) }]) + ) + ).toEqual({ min: undefined, max: undefined }); + }); + + it('should return no result if data or table is not available', () => { + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType: 'area', accessors: ['a', 'b', 'c'] }, + { layerId: 'id-b', seriesType: 'line', accessors: ['d', 'e', 'f'] }, + ] as XYLayerConfig[], + ['a', 'b'], + getActiveData([{ id: 'id-c', rows: [{ a: 100, b: 100 }] }]) // mind the layer id here + ) + ).toEqual({ min: undefined, max: undefined }); + + expect( + computeOverallDataDomain( + [ + { layerId: 'id-a', seriesType: 'bar', accessors: ['a', 'b', 'c'] }, + { layerId: 'id-b', seriesType: 'bar_stacked' }, + ] as XYLayerConfig[], + ['a', 'b'], + getActiveData([]) + ) + ).toEqual({ min: undefined, max: undefined }); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.tsx b/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.tsx index ec47350709473..8bf5f84b15bad 100644 --- a/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/threshold_helpers.tsx @@ -5,12 +5,13 @@ * 2.0. */ +import { partition } from 'lodash'; import { layerTypes } from '../../common'; import type { XYLayerConfig, YConfig } from '../../common/expressions'; import { Datatable } from '../../../../../src/plugins/expressions/public'; import type { DatasourcePublicAPI, FramePublicAPI } from '../types'; import { groupAxesByType } from './axes_configuration'; -import { isPercentageSeries } from './state_helpers'; +import { isPercentageSeries, isStackedChart } from './state_helpers'; import type { XYState } from './types'; import { checkScaleOperation } from './visualization_helpers'; @@ -91,14 +92,22 @@ export function getStaticValue( // filter and organize data dimensions into threshold groups // now pick the columnId in the active data - const { dataLayer, accessor } = getAccessorCriteriaForGroup(groupId, dataLayers, activeData); - if (groupId === 'x' && dataLayer && !layerHasNumberHistogram(dataLayer)) { + const { + dataLayers: filteredLayers, + untouchedDataLayers, + accessors, + } = getAccessorCriteriaForGroup(groupId, dataLayers, activeData); + if ( + groupId === 'x' && + filteredLayers.length && + !untouchedDataLayers.some(layerHasNumberHistogram) + ) { return fallbackValue; } return ( computeStaticValueForGroup( - dataLayer, - accessor, + filteredLayers, + accessors, activeData, groupId !== 'x' // histogram axis should compute the min based on the current data ) || fallbackValue @@ -111,54 +120,123 @@ function getAccessorCriteriaForGroup( activeData: FramePublicAPI['activeData'] ) { switch (groupId) { - case 'x': - const dataLayer = dataLayers.find(({ xAccessor }) => xAccessor); + case 'x': { + const filteredDataLayers = dataLayers.filter(({ xAccessor }) => xAccessor); + // need to reshape the dataLayers to match the other accessors format return { - dataLayer, - accessor: dataLayer?.xAccessor, + dataLayers: filteredDataLayers.map(({ accessors, xAccessor, ...rest }) => ({ + ...rest, + accessors: [xAccessor] as string[], + })), + // need the untouched ones for some checks later on + untouchedDataLayers: filteredDataLayers, + accessors: filteredDataLayers.map(({ xAccessor }) => xAccessor) as string[], }; - case 'yLeft': + } + case 'yLeft': { const { left } = groupAxesByType(dataLayers, activeData); + const leftIds = new Set(left.map(({ layer }) => layer)); + const filteredDataLayers = dataLayers.filter(({ layerId }) => leftIds.has(layerId)); return { - dataLayer: dataLayers.find(({ layerId }) => layerId === left[0]?.layer), - accessor: left[0]?.accessor, + dataLayers: filteredDataLayers, + untouchedDataLayers: filteredDataLayers, + accessors: left.map(({ accessor }) => accessor), }; - case 'yRight': + } + case 'yRight': { const { right } = groupAxesByType(dataLayers, activeData); + const rightIds = new Set(right.map(({ layer }) => layer)); + const filteredDataLayers = dataLayers.filter(({ layerId }) => rightIds.has(layerId)); return { - dataLayer: dataLayers.find(({ layerId }) => layerId === right[0]?.layer), - accessor: right[0]?.accessor, + dataLayers: filteredDataLayers, + untouchedDataLayers: filteredDataLayers, + accessors: right.map(({ accessor }) => accessor), }; + } + } +} + +export function computeOverallDataDomain( + dataLayers: Array<Pick<XYLayerConfig, 'seriesType' | 'accessors' | 'xAccessor' | 'layerId'>>, + accessorIds: string[], + activeData: NonNullable<FramePublicAPI['activeData']> +) { + const accessorMap = new Set(accessorIds); + let min: number | undefined; + let max: number | undefined; + const [stacked, unstacked] = partition(dataLayers, ({ seriesType }) => + isStackedChart(seriesType) + ); + for (const { layerId, accessors } of unstacked) { + const table = activeData[layerId]; + if (table) { + for (const accessor of accessors) { + if (accessorMap.has(accessor)) { + for (const row of table.rows) { + const value = row[accessor]; + if (typeof value === 'number') { + // when not stacked, do not keep the 0 + max = max != null ? Math.max(value, max) : value; + min = min != null ? Math.min(value, min) : value; + } + } + } + } + } + } + // stacked can span multiple layers, so compute an overall max/min by bucket + const stackedResults: Record<string, number> = {}; + for (const { layerId, accessors, xAccessor } of stacked) { + const table = activeData[layerId]; + if (table) { + for (const accessor of accessors) { + if (accessorMap.has(accessor)) { + for (const row of table.rows) { + const value = row[accessor]; + // start with a shared bucket + let bucket = 'shared'; + // but if there's an xAccessor use it as new bucket system + if (xAccessor) { + bucket = row[xAccessor]; + } + if (typeof value === 'number') { + stackedResults[bucket] = stackedResults[bucket] ?? 0; + stackedResults[bucket] += value; + } + } + } + } + } + } + + for (const value of Object.values(stackedResults)) { + // for stacked extents keep 0 in view + max = Math.max(value, max || 0, 0); + min = Math.min(value, min || 0, 0); } + + return { min, max }; } function computeStaticValueForGroup( - dataLayer: XYLayerConfig | undefined, - accessorId: string | undefined, + dataLayers: Array<Pick<XYLayerConfig, 'seriesType' | 'accessors' | 'xAccessor' | 'layerId'>>, + accessorIds: string[], activeData: NonNullable<FramePublicAPI['activeData']>, - minZeroBased: boolean + minZeroOrNegativeBase: boolean = true ) { const defaultThresholdFactor = 3 / 4; - if (dataLayer && accessorId) { - if (isPercentageSeries(dataLayer?.seriesType)) { + if (dataLayers.length && accessorIds.length) { + if (dataLayers.some(({ seriesType }) => isPercentageSeries(seriesType))) { return defaultThresholdFactor; } - const tableId = Object.keys(activeData).find((key) => - activeData[key].columns.some(({ id }) => id === accessorId) - ); - if (tableId) { - const columnMax = activeData[tableId].rows.reduce( - (max, row) => Math.max(row[accessorId], max), - -Infinity - ); - const columnMin = activeData[tableId].rows.reduce( - (max, row) => Math.min(row[accessorId], max), - Infinity - ); + + const { min, max } = computeOverallDataDomain(dataLayers, accessorIds, activeData); + + if (min != null && max != null && isFinite(min) && isFinite(max)) { // Custom axis bounds can go below 0, so consider also lower values than 0 - const finalMinValue = minZeroBased ? Math.min(0, columnMin) : columnMin; - const interval = columnMax - finalMinValue; + const finalMinValue = minZeroOrNegativeBase ? Math.min(0, min) : min; + const interval = max - finalMinValue; return Number((finalMinValue + interval * defaultThresholdFactor).toFixed(2)); } } diff --git a/x-pack/plugins/license_management/__jest__/add_license.test.js b/x-pack/plugins/license_management/__jest__/add_license.test.js index 1e36226f9174a..186601bb8d097 100644 --- a/x-pack/plugins/license_management/__jest__/add_license.test.js +++ b/x-pack/plugins/license_management/__jest__/add_license.test.js @@ -7,11 +7,6 @@ import { AddLicense } from '../public/application/sections/license_dashboard/add_license'; import { createMockLicense, getComponent } from './util'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); describe('AddLicense component when license is active', () => { test('should display correct verbiage', () => { diff --git a/x-pack/plugins/license_management/__jest__/request_trial_extension.test.js b/x-pack/plugins/license_management/__jest__/request_trial_extension.test.js index 5e14986ec53e1..bd6dfcc3c576f 100644 --- a/x-pack/plugins/license_management/__jest__/request_trial_extension.test.js +++ b/x-pack/plugins/license_management/__jest__/request_trial_extension.test.js @@ -7,11 +7,6 @@ import { RequestTrialExtension } from '../public/application/sections/license_dashboard/request_trial_extension'; import { createMockLicense, getComponent } from './util'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); describe('RequestTrialExtension component', () => { test('should not display when license is active and trial has not been used', () => { diff --git a/x-pack/plugins/license_management/__jest__/revert_to_basic.test.js b/x-pack/plugins/license_management/__jest__/revert_to_basic.test.js index ff5642f2a18db..417f3484a2d78 100644 --- a/x-pack/plugins/license_management/__jest__/revert_to_basic.test.js +++ b/x-pack/plugins/license_management/__jest__/revert_to_basic.test.js @@ -7,11 +7,6 @@ import { RevertToBasic } from '../public/application/sections/license_dashboard/revert_to_basic'; import { createMockLicense, getComponent } from './util'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); describe('RevertToBasic component', () => { test('should display when trial is active', () => { diff --git a/x-pack/plugins/license_management/__jest__/start_trial.test.js b/x-pack/plugins/license_management/__jest__/start_trial.test.js index e80b601952246..6dc6c95521f55 100644 --- a/x-pack/plugins/license_management/__jest__/start_trial.test.js +++ b/x-pack/plugins/license_management/__jest__/start_trial.test.js @@ -8,12 +8,6 @@ import { StartTrial } from '../public/application/sections/license_dashboard/start_trial'; import { createMockLicense, getComponent } from './util'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - describe('StartTrial component when trial is allowed', () => { test('display for basic license', () => { const rendered = getComponent( diff --git a/x-pack/plugins/lists/public/exceptions/api.test.ts b/x-pack/plugins/lists/public/exceptions/api.test.ts index a196999d14943..65c11bfc1dfd0 100644 --- a/x-pack/plugins/lists/public/exceptions/api.test.ts +++ b/x-pack/plugins/lists/public/exceptions/api.test.ts @@ -759,7 +759,7 @@ describe('Exceptions Lists API', () => { }); expect(httpMock.fetch).toHaveBeenCalledWith('/api/exception_lists/_export', { - method: 'GET', + method: 'POST', query: { id: 'some-id', list_id: 'list-id', diff --git a/x-pack/plugins/lists/server/routes/export_exception_list_route.ts b/x-pack/plugins/lists/server/routes/export_exception_list_route.ts index a238d0e6529ff..aa30c8a7d435d 100644 --- a/x-pack/plugins/lists/server/routes/export_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/export_exception_list_route.ts @@ -6,6 +6,7 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; +import { transformDataToNdjson } from '@kbn/securitysolution-utils'; import { exportExceptionListQuerySchema } from '@kbn/securitysolution-io-ts-list-types'; import { EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; @@ -14,7 +15,7 @@ import type { ListsPluginRouter } from '../types'; import { buildRouteValidation, buildSiemResponse, getExceptionListClient } from './utils'; export const exportExceptionListRoute = (router: ListsPluginRouter): void => { - router.get( + router.post( { options: { tags: ['access:lists-read'], @@ -26,6 +27,7 @@ export const exportExceptionListRoute = (router: ListsPluginRouter): void => { }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); + try { const { id, list_id: listId, namespace_type: namespaceType } = request.query; const exceptionLists = getExceptionListClient(context); @@ -37,11 +39,10 @@ export const exportExceptionListRoute = (router: ListsPluginRouter): void => { if (exceptionList == null) { return siemResponse.error({ - body: `list_id: ${listId} does not exist`, + body: `exception list with list_id: ${listId} does not exist`, statusCode: 400, }); } else { - const { exportData: exportList } = getExport([exceptionList]); const listItems = await exceptionLists.findExceptionListItem({ filter: undefined, listId, @@ -51,19 +52,15 @@ export const exportExceptionListRoute = (router: ListsPluginRouter): void => { sortField: 'exception-list.created_at', sortOrder: 'desc', }); + const exceptionItems = listItems?.data ?? []; - const { exportData: exportListItems, exportDetails } = getExport(listItems?.data ?? []); - - const responseBody = [ - exportList, - exportListItems, - { exception_list_items_details: exportDetails }, - ]; + const { exportData } = getExport([exceptionList, ...exceptionItems]); + const { exportDetails } = getExportDetails(exceptionItems); // TODO: Allow the API to override the name of the file to export const fileName = exceptionList.list_id; return response.ok({ - body: transformDataToNdjson(responseBody), + body: `${exportData}${exportDetails}`, headers: { 'Content-Disposition': `attachment; filename="${fileName}"`, 'Content-Type': 'application/ndjson', @@ -81,24 +78,23 @@ export const exportExceptionListRoute = (router: ListsPluginRouter): void => { ); }; -const transformDataToNdjson = (data: unknown[]): string => { - if (data.length !== 0) { - const dataString = data.map((dataItem) => JSON.stringify(dataItem)).join('\n'); - return `${dataString}\n`; - } else { - return ''; - } -}; - export const getExport = ( data: unknown[] ): { exportData: string; - exportDetails: string; } => { const ndjson = transformDataToNdjson(data); + + return { exportData: ndjson }; +}; + +export const getExportDetails = ( + items: unknown[] +): { + exportDetails: string; +} => { const exportDetails = JSON.stringify({ - exported_count: data.length, + exported_list_items_count: items.length, }); - return { exportData: ndjson, exportDetails: `${exportDetails}\n` }; + return { exportDetails: `${exportDetails}\n` }; }; diff --git a/x-pack/plugins/ml/common/types/kibana.ts b/x-pack/plugins/ml/common/types/kibana.ts index 7783a02c2dd37..cc7b68b40149f 100644 --- a/x-pack/plugins/ml/common/types/kibana.ts +++ b/x-pack/plugins/ml/common/types/kibana.ts @@ -8,7 +8,6 @@ // custom edits or fixes for default kibana types which are incomplete import type { SimpleSavedObject } from 'kibana/public'; -import type { IndexPatternAttributes } from 'src/plugins/data/common'; import type { FieldFormatsRegistry } from '../../../../../src/plugins/field_formats/common'; export type IndexPatternTitle = string; @@ -18,7 +17,6 @@ export interface Route { k7Breadcrumbs: () => any; } -export type IndexPatternSavedObject = SimpleSavedObject<IndexPatternAttributes>; // TODO define saved object type export type SavedSearchSavedObject = SimpleSavedObject<any>; diff --git a/x-pack/plugins/ml/kibana.json b/x-pack/plugins/ml/kibana.json index 310ac5d65c986..9ed05bbdc2edf 100644 --- a/x-pack/plugins/ml/kibana.json +++ b/x-pack/plugins/ml/kibana.json @@ -8,6 +8,7 @@ ], "requiredPlugins": [ "data", + "dataViews", "cloud", "features", "dataVisualizer", diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index c7e457c0b5e00..6259cecae78b5 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -135,6 +135,7 @@ export const renderApp = ( urlGenerators: deps.share.urlGenerators, maps: deps.maps, dataVisualizer: deps.dataVisualizer, + dataViews: deps.data.dataViews, }); appMountParams.onAppLeave((actions) => actions.default()); diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.ts index a64594e86a757..6fc6f298e73d8 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.ts @@ -19,12 +19,9 @@ import { i18n } from '@kbn/i18n'; import { CoreSetup } from 'src/core/public'; -import { - IndexPattern, - IFieldType, - ES_FIELD_TYPES, - KBN_FIELD_TYPES, -} from '../../../../../../../src/plugins/data/public'; +import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; + +import type { DataView, DataViewField } from '../../../../../../../src/plugins/data_views/common'; import { DEFAULT_RESULTS_FIELD } from '../../../../common/constants/data_frame_analytics'; import { extractErrorMessage } from '../../../../common/util/errors'; @@ -72,7 +69,7 @@ export const euiDataGridToolbarSettings = { showFullScreenSelector: false, }; -export const getFieldsFromKibanaIndexPattern = (indexPattern: IndexPattern): string[] => { +export const getFieldsFromKibanaIndexPattern = (indexPattern: DataView): string[] => { const allFields = indexPattern.fields.map((f) => f.name); const indexPatternFields: string[] = allFields.filter((f) => { if (indexPattern.metaFields.includes(f)) { @@ -98,7 +95,7 @@ export const getFieldsFromKibanaIndexPattern = (indexPattern: IndexPattern): str * @param RuntimeMappings */ export function getCombinedRuntimeMappings( - indexPattern: IndexPattern | undefined, + indexPattern: DataView | undefined, runtimeMappings?: RuntimeMappings ): RuntimeMappings | undefined { let combinedRuntimeMappings = {}; @@ -219,7 +216,7 @@ export const getDataGridSchemaFromESFieldType = ( }; export const getDataGridSchemaFromKibanaFieldType = ( - field: IFieldType | undefined + field: DataViewField | undefined ): string | undefined => { // Built-in values are ['boolean', 'currency', 'datetime', 'numeric', 'json'] // To fall back to the default string schema it needs to be undefined. @@ -312,7 +309,7 @@ export const getTopClasses = (row: Record<string, any>, mlResultsField: string): }; export const useRenderCellValue = ( - indexPattern: IndexPattern | undefined, + indexPattern: DataView | undefined, pagination: IndexPagination, tableItems: DataGridItem[], resultsField?: string, diff --git a/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts b/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts index ff6363ea2cc6e..fb9648f5ef4af 100644 --- a/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts +++ b/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.d.ts @@ -7,10 +7,10 @@ import { FC } from 'react'; import { SavedSearchSavedObject } from '../../../../common/types/kibana'; -import type { IIndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; declare const DataRecognizer: FC<{ - indexPattern: IIndexPattern; + indexPattern: DataView; savedSearch: SavedSearchSavedObject | null; results: { count: number; diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx index f9f8d9a370bab..72641499fe6af 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx @@ -8,15 +8,15 @@ import React from 'react'; import { shallowWithIntl } from '@kbn/test/jest'; import { FullTimeRangeSelector } from './index'; -import { Query } from 'src/plugins/data/public'; -import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { Query } from 'src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; // Create a mock for the setFullTimeRange function in the service. // The mock is hoisted to the top, so need to prefix the mock function // with 'mock' so it can be used lazily. -const mockSetFullTimeRange = jest.fn((indexPattern: IndexPattern, query: Query) => true); +const mockSetFullTimeRange = jest.fn((indexPattern: DataView, query: Query) => true); jest.mock('./full_time_range_selector_service', () => ({ - setFullTimeRange: (indexPattern: IndexPattern, query: Query) => + setFullTimeRange: (indexPattern: DataView, query: Query) => mockSetFullTimeRange(indexPattern, query), })); @@ -26,7 +26,7 @@ describe('FullTimeRangeSelector', () => { fields: [], title: 'test-index-pattern', timeFieldName: '@timestamp', - } as unknown as IndexPattern; + } as unknown as DataView; const query: Query = { language: 'kuery', diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx index f087754bd275b..3c9689c8c108b 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx @@ -8,12 +8,13 @@ import React, { FC } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { Query, IndexPattern } from 'src/plugins/data/public'; +import type { Query } from 'src/plugins/data/public'; import { EuiButton } from '@elastic/eui'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; import { setFullTimeRange } from './full_time_range_selector_service'; interface Props { - indexPattern: IndexPattern; + indexPattern: DataView; query: Query; disabled: boolean; callback?: (a: any) => void; @@ -23,7 +24,7 @@ interface Props { // to the time range of data in the index(es) mapped to the supplied Kibana index pattern or query. export const FullTimeRangeSelector: FC<Props> = ({ indexPattern, query, disabled, callback }) => { // wrapper around setFullTimeRange to allow for the calling of the optional callBack prop - async function setRange(i: IndexPattern, q: Query) { + async function setRange(i: DataView, q: Query) { const fullTimeRange = await setFullTimeRange(i, q); if (typeof callback === 'function') { callback(fullTimeRange); diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts index 1e9c1e2c1b74d..8f0d344a36f36 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector_service.ts @@ -8,11 +8,11 @@ import moment from 'moment'; import { i18n } from '@kbn/i18n'; -import { Query } from 'src/plugins/data/public'; +import type { Query } from 'src/plugins/data/public'; import dateMath from '@elastic/datemath'; import { getTimefilter, getToastNotifications } from '../../util/dependency_cache'; import { ml, GetTimeFieldRangeResponse } from '../../services/ml_api_service'; -import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; import { isPopulatedObject } from '../../../../common/util/object_utils'; import { RuntimeMappings } from '../../../../common/types/fields'; @@ -22,7 +22,7 @@ export interface TimeRange { } export async function setFullTimeRange( - indexPattern: IndexPattern, + indexPattern: DataView, query: Query ): Promise<GetTimeFieldRangeResponse> { try { diff --git a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx index b83965b52befc..d64a180bfa8b6 100644 --- a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx +++ b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx @@ -24,7 +24,7 @@ import { import { i18n } from '@kbn/i18n'; -import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import { DataView } from '../../../../../../../src/plugins/data_views/public'; import { extractErrorMessage } from '../../../../common'; import { isRuntimeMappings } from '../../../../common/util/runtime_field_utils'; import { stringHash } from '../../../../common/util/string_utils'; @@ -89,7 +89,7 @@ export interface ScatterplotMatrixProps { legendType?: LegendType; searchQuery?: ResultsSearchQuery; runtimeMappings?: RuntimeMappings; - indexPattern?: IndexPattern; + indexPattern?: DataView; } export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({ diff --git a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts index d8b5b23f68847..543ab0a0c0982 100644 --- a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts +++ b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/use_scatterplot_field_options.ts @@ -7,12 +7,12 @@ import { useMemo } from 'react'; -import type { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; import { ML__INCREMENTAL_ID } from '../../data_frame_analytics/common/fields'; export const useScatterplotFieldOptions = ( - indexPattern?: IndexPattern, + indexPattern?: DataView, includes?: string[], excludes?: string[], resultsField = '' diff --git a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts index 9d53efad86d38..93f92002c4bfd 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { IndexPattern } from '../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../src/plugins/data_views/public'; export const indexPatternMock = { id: 'the-index-pattern-id', title: 'the-index-pattern-title', fields: [], -} as unknown as IndexPattern; +} as unknown as DataView; diff --git a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts index 7dfbcf1675692..571ce8ac3f423 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IndexPatternsContract } from '../../../../../../../../src/plugins/data/public'; +import type { DataViewsContract } from '../../../../../../../../src/plugins/data_views/public'; export const indexPatternsMock = new (class { fieldFormats = []; @@ -19,4 +19,4 @@ export const indexPatternsMock = new (class { getIds = jest.fn(); getTitles = jest.fn(); make = jest.fn(); -})() as unknown as IndexPatternsContract; +})() as unknown as DataViewsContract; diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts index 02c0945cf998f..cd7059b5302f2 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts @@ -6,15 +6,15 @@ */ import React from 'react'; -import { IndexPattern, IndexPatternsContract } from '../../../../../../../src/plugins/data/public'; +import { DataView, DataViewsContract } from '../../../../../../../src/plugins/data_views/public'; import { SavedSearchSavedObject } from '../../../../common/types/kibana'; import { MlServicesContext } from '../../app'; export interface MlContextValue { combinedQuery: any; - currentIndexPattern: IndexPattern; // TODO this should be IndexPattern or null + currentIndexPattern: DataView; // TODO this should be IndexPattern or null currentSavedSearch: SavedSearchSavedObject | null; - indexPatterns: IndexPatternsContract; + indexPatterns: DataViewsContract; kibanaConfig: any; // IUiSettingsClient; kibanaVersion: string; } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts index e1f0db4e9291c..a235885a9a5b7 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts @@ -9,7 +9,7 @@ import { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; import { extractErrorMessage } from '../../../../common/util/errors'; @@ -34,7 +34,7 @@ export const useResultsViewConfig = (jobId: string) => { const mlContext = useMlContext(); const trainedModelsApiService = useTrainedModelsApiService(); - const [indexPattern, setIndexPattern] = useState<IndexPattern | undefined>(undefined); + const [indexPattern, setIndexPattern] = useState<DataView | undefined>(undefined); const [indexPatternErrorMessage, setIndexPatternErrorMessage] = useState<undefined | string>( undefined ); @@ -99,7 +99,7 @@ export const useResultsViewConfig = (jobId: string) => { ? jobConfigUpdate.dest.index[0] : jobConfigUpdate.dest.index; const destIndexPatternId = getIndexPatternIdFromName(destIndex) || destIndex; - let indexP: IndexPattern | undefined; + let indexP: DataView | undefined; try { indexP = await mlContext.indexPatterns.get(destIndexPatternId); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts index 60a5a548c8621..f3779e1968985 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -11,7 +11,7 @@ import { estypes } from '@elastic/elasticsearch'; import { EuiDataGridColumn } from '@elastic/eui'; import { CoreSetup } from 'src/core/public'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { isRuntimeMappings } from '../../../../../../common/util/runtime_field_utils'; import { RuntimeMappings } from '../../../../../../common/types/fields'; import { DEFAULT_SAMPLER_SHARD_SIZE } from '../../../../../../common/constants/field_histograms'; @@ -52,13 +52,14 @@ function getRuntimeFieldColumns(runtimeMappings: RuntimeMappings) { }); } -function getIndexPatternColumns(indexPattern: IndexPattern, fieldsFilter: string[]) { +function getIndexPatternColumns(indexPattern: DataView, fieldsFilter: string[]) { const { fields } = newJobCapsServiceAnalytics; return fields .filter((field) => fieldsFilter.includes(field.name)) .map((field) => { const schema = + // @ts-expect-error field is not DataViewField getDataGridSchemaFromESFieldType(field.type) || getDataGridSchemaFromKibanaFieldType(field); return { @@ -71,7 +72,7 @@ function getIndexPatternColumns(indexPattern: IndexPattern, fieldsFilter: string } export const useIndexData = ( - indexPattern: IndexPattern, + indexPattern: DataView, query: Record<string, any> | undefined, toastNotifications: CoreSetup['notifications']['toasts'], runtimeMappings?: RuntimeMappings diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx index d67473d9d3220..2c2df0cd3d905 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiDataGridColumn, EuiSpacer, EuiText } from '@elastic/eui'; -import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../../src/plugins/data_views/public'; import { isClassificationAnalysis, @@ -104,7 +104,7 @@ const getResultsSectionHeaderItems = ( interface ExpandableSectionResultsProps { colorRange?: ReturnType<typeof useColorRange>; indexData: UseIndexDataReturnType; - indexPattern?: IndexPattern; + indexPattern?: DataView; jobConfig?: DataFrameAnalyticsConfig; needsDestIndexPattern: boolean; searchQuery: SavedSearchQuery; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx index 1a5f1bad997e2..3639836c6be01 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx @@ -13,7 +13,7 @@ import { debounce } from 'lodash'; import { fromKueryExpression, luceneStringToDsl, toElasticsearchQuery } from '@kbn/es-query'; import { estypes } from '@elastic/elasticsearch'; import { Dictionary } from '../../../../../../../common/types/common'; -import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common'; +import { DataView } from '../../../../../../../../../../src/plugins/data_views/common'; import { Query, QueryStringInput } from '../../../../../../../../../../src/plugins/data/public'; import { @@ -29,7 +29,7 @@ interface ErrorMessage { } export interface ExplorationQueryBarProps { - indexPattern: IIndexPattern; + indexPattern: DataView; setSearchQuery: (update: { queryString: string; query?: SavedSearchQuery; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx index 416d2f8b29d3b..41c434c7160cf 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx @@ -7,7 +7,7 @@ import React, { FC } from 'react'; -import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../../src/plugins/data_views/public'; import { getToastNotifications } from '../../../../../util/dependency_cache'; import { useMlKibana } from '../../../../../contexts/kibana'; @@ -22,7 +22,7 @@ import { ExpandableSectionResults } from '../expandable_section'; import { useExplorationResults } from './use_exploration_results'; interface Props { - indexPattern: IndexPattern; + indexPattern: DataView; jobConfig: DataFrameAnalyticsConfig; jobStatus?: DataFrameTaskStateType; needsDestIndexPattern: boolean; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index 02e3f0abac4be..6e0d513a35b9a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -13,7 +13,7 @@ import { CoreSetup } from 'src/core/public'; import { i18n } from '@kbn/i18n'; import { MlApiServices } from '../../../../../services/ml_api_service'; -import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../../src/plugins/data_views/public'; import { DataLoader } from '../../../../../datavisualizer/index_based/data_loader'; @@ -41,7 +41,7 @@ import { FeatureImportanceBaseline } from '../../../../../../../common/types/fea import { useExplorationDataGrid } from './use_exploration_data_grid'; export const useExplorationResults = ( - indexPattern: IndexPattern | undefined, + indexPattern: DataView | undefined, jobConfig: DataFrameAnalyticsConfig | undefined, searchQuery: SavedSearchQuery, toastNotifications: CoreSetup['notifications']['toasts'], diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts index d630fedc72d3f..d0f048ac02606 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts @@ -9,7 +9,7 @@ import { useEffect, useMemo } from 'react'; import { EuiDataGridColumn } from '@elastic/eui'; -import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../../src/plugins/data_views/public'; import { DataLoader } from '../../../../../datavisualizer/index_based/data_loader'; @@ -41,7 +41,7 @@ import { getFeatureCount, getOutlierScoreFieldName } from './common'; import { useExplorationDataGrid } from '../exploration_results_table/use_exploration_data_grid'; export const useOutlierData = ( - indexPattern: IndexPattern | undefined, + indexPattern: DataView | undefined, jobConfig: DataFrameAnalyticsConfig | undefined, searchQuery: SavedSearchQuery ): UseIndexDataReturnType => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx index a3f18801b88f9..8ef743d2eea9f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx @@ -9,7 +9,6 @@ import { EuiToolTip } from '@elastic/eui'; import React, { FC } from 'react'; import { cloneDeep, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { IIndexPattern } from 'src/plugins/data/common'; import { DeepReadonly } from '../../../../../../../common/types/common'; import { DataFrameAnalyticsConfig, isOutlierAnalysis } from '../../../../common'; import { isClassificationAnalysis, isRegressionAnalysis } from '../../../../common/analytics'; @@ -401,13 +400,11 @@ export const useNavigateToWizardWithClonedJob = () => { const { services: { notifications: { toasts }, - savedObjects, + data: { dataViews }, }, } = useMlKibana(); const navigateToPath = useNavigateToPath(); - const savedObjectsClient = savedObjects.client; - return async (item: Pick<DataFrameAnalyticsListRow, 'config' | 'stats'>) => { const sourceIndex = Array.isArray(item.config.source.index) ? item.config.source.index.join(',') @@ -415,19 +412,9 @@ export const useNavigateToWizardWithClonedJob = () => { let sourceIndexId; try { - const response = await savedObjectsClient.find<IIndexPattern>({ - type: 'index-pattern', - perPage: 10, - search: `"${sourceIndex}"`, - searchFields: ['title'], - fields: ['title'], - }); - - const ip = response.savedObjects.find( - (obj) => obj.attributes.title.toLowerCase() === sourceIndex.toLowerCase() - ); - if (ip !== undefined) { - sourceIndexId = ip.id; + const dv = (await dataViews.find(sourceIndex)).find(({ title }) => title === sourceIndex); + if (dv !== undefined) { + sourceIndexId = dv.id; } else { toasts.addDanger( i18n.translate('xpack.ml.dataframe.analyticsList.noSourceIndexPatternForClone', { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx index 6b26e3823d2ef..ad6a59bf01c0e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx @@ -30,7 +30,7 @@ jest.mock('../../../../../../application/util/dependency_cache', () => ({ jest.mock('../../../../../contexts/kibana', () => ({ useMlKibana: () => ({ - services: mockCoreServices.createStart(), + services: { ...mockCoreServices.createStart(), data: { data_view: { find: jest.fn() } } }, }), useNotifications: () => { return { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx index 91871015d2add..0d2025c0d049a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx @@ -8,9 +8,6 @@ import React, { useEffect, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; - -import { IIndexPattern } from 'src/plugins/data/common'; - import { extractErrorMessage } from '../../../../../../../common/util/errors'; import { useMlKibana } from '../../../../../contexts/kibana'; @@ -48,8 +45,9 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { const [indexPatternExists, setIndexPatternExists] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false); - const { savedObjects } = useMlKibana().services; - const savedObjectsClient = savedObjects.client; + const { + data: { dataViews }, + } = useMlKibana().services; const indexName = item?.config.dest.index ?? ''; @@ -57,17 +55,8 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { const checkIndexPatternExists = async () => { try { - const response = await savedObjectsClient.find<IIndexPattern>({ - type: 'index-pattern', - perPage: 10, - search: `"${indexName}"`, - searchFields: ['title'], - fields: ['title'], - }); - const ip = response.savedObjects.find( - (obj) => obj.attributes.title.toLowerCase() === indexName.toLowerCase() - ); - if (ip !== undefined) { + const dv = (await dataViews.find(indexName)).find(({ title }) => title === indexName); + if (dv !== undefined) { setIndexPatternExists(true); } else { setIndexPatternExists(false); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx index 7e90a4e3ed44a..6e663318d2dc6 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx @@ -87,6 +87,7 @@ jest.mock('../../../../../util/index_utils', () => { async (id: string): Promise<IndexPatternAndSavedSearch> => { return { indexPattern: { + // @ts-expect-error fields should not be empty fields: [], title: id === 'the-remote-saved-search-id' diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts b/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts index a5fabc12c83df..1dccd54f68a38 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts @@ -7,7 +7,7 @@ import { CoreSetup } from 'src/core/public'; -import { IndexPattern } from '../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../src/plugins/data_views/public'; import { SavedSearchQuery } from '../../../contexts/ml'; import { OMIT_FIELDS } from '../../../../../common/constants/field_types'; @@ -22,15 +22,12 @@ import { RuntimeMappings } from '../../../../../common/types/fields'; const MAX_EXAMPLES_DEFAULT: number = 10; export class DataLoader { - private _indexPattern: IndexPattern; + private _indexPattern: DataView; private _runtimeMappings: RuntimeMappings; private _indexPatternTitle: IndexPatternTitle = ''; private _maxExamples: number = MAX_EXAMPLES_DEFAULT; - constructor( - indexPattern: IndexPattern, - toastNotifications?: CoreSetup['notifications']['toasts'] - ) { + constructor(indexPattern: DataView, toastNotifications?: CoreSetup['notifications']['toasts']) { this._indexPattern = indexPattern; this._runtimeMappings = this._indexPattern.getComputedFields().runtimeFields as RuntimeMappings; this._indexPatternTitle = indexPattern.title; diff --git a/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx b/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx index 6e8b5f762558f..f57d2c1b01d98 100644 --- a/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx @@ -10,7 +10,7 @@ import { EuiCode, EuiInputPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { fromKueryExpression, luceneStringToDsl, toElasticsearchQuery } from '@kbn/es-query'; import { Query, QueryStringInput } from '../../../../../../../../src/plugins/data/public'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; +import { DataView } from '../../../../../../../../src/plugins/data_views/common'; import { SEARCH_QUERY_LANGUAGE, ErrorMessage } from '../../../../../common/constants/search'; import { explorerService } from '../../explorer_dashboard_service'; import { InfluencersFilterQuery } from '../../../../../common/types/es_client'; @@ -24,7 +24,7 @@ export function getKqlQueryValues({ }: { inputString: string | { [key: string]: any }; queryLanguage: string; - indexPattern: IIndexPattern; + indexPattern: DataView; }): { clearSettings: boolean; settings: any } { let influencersFilterQuery: InfluencersFilterQuery = {}; const filteredFields: string[] = []; @@ -89,7 +89,7 @@ function getInitSearchInputState({ interface ExplorerQueryBarProps { filterActive: boolean; filterPlaceHolder: string; - indexPattern: IIndexPattern; + indexPattern: DataView; queryString?: string; updateLanguage: (language: string) => void; } diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx index f6769abb610b8..11e4c14cd4ab2 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { CustomUrlEditor } from './editor'; import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import { CustomUrlSettings } from './utils'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; +import { DataView } from '../../../../../../../../src/plugins/data_views/common'; function prepareTest(customUrl: CustomUrlSettings, setEditCustomUrlFn: (url: UrlConfig) => void) { const savedCustomUrls = [ @@ -50,7 +50,7 @@ function prepareTest(customUrl: CustomUrlSettings, setEditCustomUrlFn: (url: Url const indexPatterns = [ { id: 'pattern1', title: 'Index Pattern 1' }, { id: 'pattern2', title: 'Index Pattern 2' }, - ] as IIndexPattern[]; + ] as DataView[]; const queryEntityFieldNames = ['airline']; diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx index e22eb1484df2e..7dd779ead7892 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx @@ -29,7 +29,7 @@ import { isValidLabel } from '../../../util/custom_url_utils'; import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import { UrlConfig } from '../../../../../common/types/custom_urls'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; +import { DataView } from '../../../../../../../../src/plugins/data_views/common'; function getLinkToOptions() { return [ @@ -59,7 +59,7 @@ interface CustomUrlEditorProps { setEditCustomUrl: (url: any) => void; savedCustomUrls: UrlConfig[]; dashboards: any[]; - indexPatterns: IIndexPattern[]; + indexPatterns: DataView[]; queryEntityFieldNames: string[]; } diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts index 87000cdabd913..1f815759c6242 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IIndexPattern } from 'src/plugins/data/common'; +import { DataView } from '../../../../../../../../src/plugins/data_views/common'; import { UrlConfig } from '../../../../../common/types/custom_urls'; import { Job } from '../../../../../common/types/anomaly_detection_jobs'; import { TimeRangeType } from './constants'; @@ -34,7 +34,7 @@ export function isValidCustomUrlSettingsTimeRange(timeRangeSettings: any): boole export function getNewCustomUrlDefaults( job: Job, dashboards: any[], - indexPatterns: IIndexPattern[] + indexPatterns: DataView[] ): CustomUrlSettings; export function getQueryEntityFieldNames(job: Job): string[]; export function isValidCustomUrlSettings( diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts index 3a14715bca4b9..32e99e3e433e0 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IIndexPattern } from 'src/plugins/data/common'; +import type { DataView } from 'src/plugins/data_views/common'; export function loadSavedDashboards(maxNumber: number): Promise<any[]>; -export function loadIndexPatterns(maxNumber: number): Promise<IIndexPattern[]>; +export function loadIndexPatterns(maxNumber: number): Promise<DataView[]>; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js index 8ce92ffa38479..ad192a738174e 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js @@ -8,7 +8,7 @@ import { difference } from 'lodash'; import { getNewJobLimits } from '../../../../services/ml_server_info'; import { processCreatedBy } from '../../../../../../common/util/job_utils'; -import { getSavedObjectsClient } from '../../../../util/dependency_cache'; +import { getSavedObjectsClient, getDataViews } from '../../../../util/dependency_cache'; import { ml } from '../../../../services/ml_api_service'; export function saveJob(job, newJobData, finish) { @@ -107,26 +107,12 @@ export function loadIndexPatterns(maxNumber) { // TODO - amend loadIndexPatterns in index_utils.js to do the request, // without needing an Angular Provider. return new Promise((resolve, reject) => { - const savedObjectsClient = getSavedObjectsClient(); - savedObjectsClient - .find({ - type: 'index-pattern', - fields: ['title'], - perPage: maxNumber, - }) - .then((resp) => { - const savedObjects = resp.savedObjects; - if (savedObjects !== undefined) { - const indexPatterns = savedObjects.map((savedObj) => { - return { id: savedObj.id, title: savedObj.attributes.title }; - }); - - indexPatterns.sort((dash1, dash2) => { - return dash1.title.localeCompare(dash2.title); - }); - - resolve(indexPatterns); - } + const dataViewsContract = getDataViews(); + dataViewsContract + .find('*', maxNumber) + .then((dataViews) => { + const sortedDataViews = dataViews.sort((a, b) => a.title.localeCompare(b.title)); + resolve(sortedDataViews); }) .catch((resp) => { reject(resp); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx index ce93080558016..46ac1dbd01b7f 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx @@ -37,7 +37,7 @@ import { loadSavedDashboards, loadIndexPatterns } from '../edit_utils'; import { openCustomUrlWindow } from '../../../../../util/custom_url_utils'; import { Job } from '../../../../../../../common/types/anomaly_detection_jobs'; import { UrlConfig } from '../../../../../../../common/types/custom_urls'; -import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common'; +import { DataView } from '../../../../../../../../../../src/plugins/data_views/common'; import { MlKibanaReactContextValue } from '../../../../../contexts/kibana'; const MAX_NUMBER_DASHBOARDS = 1000; @@ -54,7 +54,7 @@ interface CustomUrlsProps { interface CustomUrlsState { customUrls: UrlConfig[]; dashboards: any[]; - indexPatterns: IIndexPattern[]; + indexPatterns: DataView[]; queryEntityFieldNames: string[]; editorOpen: boolean; editorSettings?: CustomUrlSettings; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts index 9c8f34260def0..5898a9dec1ad3 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts @@ -19,7 +19,7 @@ import { ml } from '../../../../services/ml_api_service'; import { mlResultsService } from '../../../../services/results_service'; import { getCategoryFields as getCategoryFieldsOrig } from './searches'; import { aggFieldPairsCanBeCharted } from '../job_creator/util/general'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/common'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/common'; type DetectorIndex = number; export interface LineChartPoint { @@ -41,7 +41,7 @@ export class ChartLoader { private _timeFieldName: string = ''; private _query: object = {}; - constructor(indexPattern: IndexPattern, query: object) { + constructor(indexPattern: DataView, query: object) { this._indexPatternTitle = indexPattern.title; this._query = query; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts index cb842937f1ede..9667465eb210d 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/index_pattern_context.ts @@ -7,7 +7,7 @@ import React from 'react'; -import { IIndexPattern } from 'src/plugins/data/public'; +import { DataView } from '../../../../../../../../src/plugins/data_views/common'; -export type IndexPatternContextValue = IIndexPattern | null; +export type IndexPatternContextValue = DataView | null; export const IndexPatternContext = React.createContext<IndexPatternContextValue>(null); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts index 35847839b02a0..3d8c34e0e5967 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts @@ -21,7 +21,7 @@ import { JOB_TYPE } from '../../../../../../common/constants/new_job'; import { getRichDetectors } from './util/general'; import { isValidJson } from '../../../../../../common/util/validation_utils'; import { ml } from '../../../../services/ml_api_service'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; export interface RichDetector { agg: Aggregation | null; @@ -40,11 +40,7 @@ export class AdvancedJobCreator extends JobCreator { private _richDetectors: RichDetector[] = []; private _queryString: string; - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { super(indexPattern, savedSearch, query); this._queryString = JSON.stringify(this._datafeed_config.query); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts index 128a541ff9f96..b46d3b539b44a 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts @@ -6,7 +6,7 @@ */ import { isEqual } from 'lodash'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { SavedSearchSavedObject } from '../../../../../../common/types/kibana'; import { JobCreator } from './job_creator'; import { Field, Aggregation, mlCategory } from '../../../../../../common/types/fields'; @@ -47,11 +47,7 @@ export class CategorizationJobCreator extends JobCreator { private _partitionFieldName: string | null = null; private _ccsVersionFailure: boolean = false; - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { super(indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.CATEGORIZATION; this._examplesLoader = new CategorizationExamplesLoader(this, indexPattern, query); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts index e6cfe52933617..a44b4bdef60c4 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts @@ -40,13 +40,13 @@ import { filterRuntimeMappings } from './util/filter_runtime_mappings'; import { parseInterval } from '../../../../../../common/util/parse_interval'; import { Calendar } from '../../../../../../common/types/calendars'; import { mlCalendarService } from '../../../../services/calendar_service'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { getDatafeedAggregations } from '../../../../../../common/util/datafeed_utils'; import { getFirstKeyInObject } from '../../../../../../common/util/object_utils'; export class JobCreator { protected _type: JOB_TYPE = JOB_TYPE.SINGLE_METRIC; - protected _indexPattern: IndexPattern; + protected _indexPattern: DataView; protected _savedSearch: SavedSearchSavedObject | null; protected _indexPatternTitle: IndexPatternTitle = ''; protected _job_config: Job; @@ -74,11 +74,7 @@ export class JobCreator { protected _wizardInitialized$ = new BehaviorSubject<boolean>(false); public wizardInitialized$ = this._wizardInitialized$.asObservable(); - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { this._indexPattern = indexPattern; this._savedSearch = savedSearch; this._indexPatternTitle = indexPattern.title; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts index 8c77ae5def102..6af3df888514c 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts @@ -10,7 +10,7 @@ import { SingleMetricJobCreator } from './single_metric_job_creator'; import { MultiMetricJobCreator } from './multi_metric_job_creator'; import { PopulationJobCreator } from './population_job_creator'; import { AdvancedJobCreator } from './advanced_job_creator'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { CategorizationJobCreator } from './categorization_job_creator'; import { RareJobCreator } from './rare_job_creator'; @@ -18,7 +18,7 @@ import { JOB_TYPE } from '../../../../../../common/constants/new_job'; export const jobCreatorFactory = (jobType: JOB_TYPE) => - (indexPattern: IndexPattern, savedSearch: SavedSearchSavedObject | null, query: object) => { + (indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) => { let jc; switch (jobType) { case JOB_TYPE.SINGLE_METRIC: diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts index f63aa1b569a2c..12543f34003d5 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts @@ -17,7 +17,7 @@ import { Job, Datafeed, Detector } from '../../../../../../common/types/anomaly_ import { createBasicDetector } from './util/default_configs'; import { JOB_TYPE, CREATED_BY_LABEL } from '../../../../../../common/constants/new_job'; import { getRichDetectors } from './util/general'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { isSparseDataJob } from './util/general'; export class MultiMetricJobCreator extends JobCreator { @@ -27,11 +27,7 @@ export class MultiMetricJobCreator extends JobCreator { protected _type: JOB_TYPE = JOB_TYPE.MULTI_METRIC; - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { super(indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.MULTI_METRIC; this._wizardInitialized$.next(true); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts index 24b3192231211..7f001ce334462 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts @@ -17,7 +17,7 @@ import { Job, Datafeed, Detector } from '../../../../../../common/types/anomaly_ import { createBasicDetector } from './util/default_configs'; import { JOB_TYPE, CREATED_BY_LABEL } from '../../../../../../common/constants/new_job'; import { getRichDetectors } from './util/general'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; export class PopulationJobCreator extends JobCreator { // a population job has one overall over (split) field, which is the same for all detectors @@ -26,11 +26,7 @@ export class PopulationJobCreator extends JobCreator { private _byFields: SplitField[] = []; protected _type: JOB_TYPE = JOB_TYPE.POPULATION; - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { super(indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.POPULATION; this._wizardInitialized$.next(true); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts index 73050dc4b7834..8973aa655b83d 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts @@ -11,7 +11,7 @@ import { Field, SplitField, Aggregation } from '../../../../../../common/types/f import { Job, Datafeed, Detector } from '../../../../../../common/types/anomaly_detection_jobs'; import { JOB_TYPE, CREATED_BY_LABEL } from '../../../../../../common/constants/new_job'; import { getRichDetectors } from './util/general'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { isSparseDataJob } from './util/general'; import { ML_JOB_AGGREGATION } from '../../../../../../common/constants/aggregation_types'; @@ -26,11 +26,7 @@ export class RareJobCreator extends JobCreator { private _rareAgg: Aggregation; private _freqRareAgg: Aggregation; - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { super(indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.RARE; this._wizardInitialized$.next(true); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts index 57ff76979ea14..9c4fd52888c82 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts @@ -22,17 +22,13 @@ import { } from '../../../../../../common/constants/aggregation_types'; import { JOB_TYPE, CREATED_BY_LABEL } from '../../../../../../common/constants/new_job'; import { getRichDetectors } from './util/general'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { isSparseDataJob } from './util/general'; export class SingleMetricJobCreator extends JobCreator { protected _type: JOB_TYPE = JOB_TYPE.SINGLE_METRIC; - constructor( - indexPattern: IndexPattern, - savedSearch: SavedSearchSavedObject | null, - query: object - ) { + constructor(indexPattern: DataView, savedSearch: SavedSearchSavedObject | null, query: object) { super(indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.SINGLE_METRIC; this._wizardInitialized$.next(true); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts index 641eda3dbf3e8..6e65bde879379 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../../../src/plugins/data_views/public'; import { IndexPatternTitle } from '../../../../../../common/types/kibana'; import { CategorizationJobCreator } from '../job_creator'; import { ml } from '../../../../services/ml_api_service'; @@ -20,7 +20,7 @@ export class CategorizationExamplesLoader { private _timeFieldName: string = ''; private _query: object = {}; - constructor(jobCreator: CategorizationJobCreator, indexPattern: IndexPattern, query: object) { + constructor(jobCreator: CategorizationJobCreator, indexPattern: DataView, query: object) { this._jobCreator = jobCreator; this._indexPatternTitle = indexPattern.title; this._query = query; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts index ba750795e4f8f..03428bd47e490 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { ApplicationStart } from 'kibana/public'; -import { IndexPatternsContract } from '../../../../../../../../../src/plugins/data/public'; +import type { ApplicationStart } from 'kibana/public'; +import type { DataViewsContract } from '../../../../../../../../../src/plugins/data_views/public'; import { mlJobService } from '../../../../services/job_service'; import { loadIndexPatterns, getIndexPatternIdFromName } from '../../../../util/index_utils'; import { Datafeed, Job } from '../../../../../../common/types/anomaly_detection_jobs'; import { CREATED_BY_LABEL, JOB_TYPE } from '../../../../../../common/constants/new_job'; export async function preConfiguredJobRedirect( - indexPatterns: IndexPatternsContract, + indexPatterns: DataViewsContract, basePath: string, navigateToUrl: ApplicationStart['navigateToUrl'] ) { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts index 3f19f3137934e..12beda414bbea 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts @@ -6,7 +6,7 @@ */ import { IUiSettingsClient } from 'kibana/public'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; +import { DataView } from '../../../../../../../../src/plugins/data_views/common'; import { SavedSearchSavedObject } from '../../../../../common/types/kibana'; import { createSearchItems } from './new_job_utils'; @@ -14,7 +14,7 @@ describe('createSearchItems', () => { const kibanaConfig = {} as IUiSettingsClient; const indexPattern = { fields: [], - } as unknown as IIndexPattern; + } as unknown as DataView; let savedSearch = {} as unknown as SavedSearchSavedObject; beforeEach(() => { diff --git a/x-pack/plugins/ml/public/application/routing/resolvers.ts b/x-pack/plugins/ml/public/application/routing/resolvers.ts index f6364ecc6568f..3479005809efb 100644 --- a/x-pack/plugins/ml/public/application/routing/resolvers.ts +++ b/x-pack/plugins/ml/public/application/routing/resolvers.ts @@ -11,7 +11,7 @@ import { checkGetJobsCapabilitiesResolver } from '../capabilities/check_capabili import { getMlNodeCount } from '../ml_nodes_check/check_ml_nodes'; import { loadMlServerInfo } from '../services/ml_server_info'; -import { IndexPatternsContract } from '../../../../../../src/plugins/data/public'; +import type { DataViewsContract } from '../../../../../../src/plugins/data_views/public'; export interface Resolvers { [name: string]: () => Promise<any>; @@ -21,7 +21,7 @@ export interface ResolverResults { } interface BasicResolverDependencies { - indexPatterns: IndexPatternsContract; + indexPatterns: DataViewsContract; redirectToMlAccessDeniedPage: () => Promise<void>; } diff --git a/x-pack/plugins/ml/public/application/routing/router.tsx b/x-pack/plugins/ml/public/application/routing/router.tsx index c2129ef18df3a..847dcc1ae1107 100644 --- a/x-pack/plugins/ml/public/application/routing/router.tsx +++ b/x-pack/plugins/ml/public/application/routing/router.tsx @@ -9,9 +9,13 @@ import React, { useEffect, FC } from 'react'; import { useHistory, useLocation, Router, Route, RouteProps } from 'react-router-dom'; import { Location } from 'history'; -import { AppMountParameters, IUiSettingsClient, ChromeStart } from 'kibana/public'; -import { ChromeBreadcrumb } from 'kibana/public'; -import { IndexPatternsContract } from 'src/plugins/data/public'; +import type { + AppMountParameters, + IUiSettingsClient, + ChromeStart, + ChromeBreadcrumb, +} from 'kibana/public'; +import type { DataViewsContract } from 'src/plugins/data_views/public'; import { useMlKibana, useNavigateToPath } from '../contexts/kibana'; import { MlContext, MlContextValue } from '../contexts/ml'; @@ -39,7 +43,7 @@ export interface PageProps { interface PageDependencies { config: IUiSettingsClient; history: AppMountParameters['history']; - indexPatterns: IndexPatternsContract; + indexPatterns: DataViewsContract; setBreadcrumbs: ChromeStart['setBreadcrumbs']; redirectToMlAccessDeniedPage: () => Promise<void>; } diff --git a/x-pack/plugins/ml/public/application/services/field_format_service.ts b/x-pack/plugins/ml/public/application/services/field_format_service.ts index 18b489682318e..fe6fc7751bb85 100644 --- a/x-pack/plugins/ml/public/application/services/field_format_service.ts +++ b/x-pack/plugins/ml/public/application/services/field_format_service.ts @@ -8,7 +8,7 @@ import { mlFunctionToESAggregation } from '../../../common/util/job_utils'; import { getIndexPatternById, getIndexPatternIdFromName } from '../util/index_utils'; import { mlJobService } from './job_service'; -import { IndexPattern } from '../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../src/plugins/data_views/public'; type FormatsByJobId = Record<string, any>; type IndexPatternIdsByJob = Record<string, any>; @@ -66,11 +66,7 @@ class FieldFormatService { // Utility for returning the FieldFormat from a full populated Kibana index pattern object // containing the list of fields by name with their formats. - getFieldFormatFromIndexPattern( - fullIndexPattern: IndexPattern, - fieldName: string, - esAggName: string - ) { + getFieldFormatFromIndexPattern(fullIndexPattern: DataView, fieldName: string, esAggName: string) { // Don't use the field formatter for distinct count detectors as // e.g. distinct_count(clientip) should be formatted as a count, not as an IP address. let fieldFormat; diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts index d3b407c2bb65a..02b2e573f8c69 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IIndexPattern, IndexPatternsContract } from '../../../../../../../src/plugins/data/public'; +import { DataView, DataViewsContract } from '../../../../../../../src/plugins/data_views/public'; import { getIndexPatternAndSavedSearch } from '../../util/index_utils'; import { JobType } from '../../../../common/types/saved_objects'; import { newJobCapsServiceAnalytics } from '../new_job_capabilities/new_job_capabilities_service_analytics'; @@ -19,7 +19,7 @@ export const DATA_FRAME_ANALYTICS = 'data-frame-analytics'; export function loadNewJobCapabilities( indexPatternId: string, savedSearchId: string, - indexPatterns: IndexPatternsContract, + indexPatterns: DataViewsContract, jobType: JobType ) { return new Promise(async (resolve, reject) => { @@ -29,7 +29,7 @@ export function loadNewJobCapabilities( if (indexPatternId !== undefined) { // index pattern is being used - const indexPattern: IIndexPattern = await indexPatterns.get(indexPatternId); + const indexPattern: DataView = await indexPatterns.get(indexPatternId); await serviceToUse.initializeFromIndexPattern(indexPattern); resolve(serviceToUse.newJobCaps); } else if (savedSearchId !== undefined) { diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts index 8c515255927b4..49c8b08007d52 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts @@ -6,7 +6,7 @@ */ import { newJobCapsService } from './new_job_capabilities_service'; -import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; // there is magic happening here. starting the include name with `mock..` // ensures it can be lazily loaded by the jest.mock function below. @@ -23,7 +23,7 @@ jest.mock('../ml_api_service', () => ({ const indexPattern = { id: 'cloudwatch-*', title: 'cloudwatch-*', -} as unknown as IndexPattern; +} as unknown as DataView; describe('new_job_capabilities_service', () => { describe('cloudwatch newJobCaps()', () => { diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts index c17f379355cea..45dc71ed6a6b9 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts @@ -11,7 +11,8 @@ import { FieldId, EVENT_RATE_FIELD_ID, } from '../../../../common/types/fields'; -import { ES_FIELD_TYPES, IIndexPattern } from '../../../../../../../src/plugins/data/public'; +import { ES_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; +import { DataView } from '../../../../../../../src/plugins/data_views/public'; import { ml } from '../ml_api_service'; import { processTextAndKeywordFields, NewJobCapabilitiesServiceBase } from './new_job_capabilities'; @@ -36,7 +37,7 @@ class NewJobCapsService extends NewJobCapabilitiesServiceBase { } public async initializeFromIndexPattern( - indexPattern: IIndexPattern, + indexPattern: DataView, includeEventRateField = true, removeTextFields = true ) { diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts index 3a362a88e40bb..f8f9ae6b2b0a3 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts @@ -6,7 +6,8 @@ */ import { Field, NewJobCapsResponse } from '../../../../common/types/fields'; -import { ES_FIELD_TYPES, IIndexPattern } from '../../../../../../../src/plugins/data/public'; +import { ES_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; +import { DataView } from '../../../../../../../src/plugins/data_views/public'; import { processTextAndKeywordFields, NewJobCapabilitiesServiceBase } from './new_job_capabilities'; import { ml } from '../ml_api_service'; @@ -42,7 +43,7 @@ export function removeNestedFieldChildren(resp: NewJobCapsResponse, indexPattern } class NewJobCapsServiceAnalytics extends NewJobCapabilitiesServiceBase { - public async initializeFromIndexPattern(indexPattern: IIndexPattern) { + public async initializeFromIndexPattern(indexPattern: DataView) { try { const resp: NewJobCapsResponse = await ml.dataFrameAnalytics.newJobCapsAnalytics( indexPattern.title, diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts index eaf30d9894f60..ec2a2a1077a7f 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/remove_nested_field_children.test.ts @@ -6,7 +6,7 @@ */ import { removeNestedFieldChildren } from './new_job_capabilities_service_analytics'; -import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import type { DataView } from '../../../../../../../src/plugins/data_views/public'; // there is magic happening here. starting the include name with `mock..` // ensures it can be lazily loaded by the jest.mock function below. @@ -15,7 +15,7 @@ import nestedFieldIndexResponse from '../__mocks__/nested_field_index_response.j const indexPattern = { id: 'nested-field-index', title: 'nested-field-index', -} as unknown as IndexPattern; +} as unknown as DataView; describe('removeNestedFieldChildren', () => { describe('cloudwatch newJobCapsAnalytics()', () => { diff --git a/x-pack/plugins/ml/public/application/util/dependency_cache.ts b/x-pack/plugins/ml/public/application/util/dependency_cache.ts index 4a3194ed4113f..7b6b75677dddd 100644 --- a/x-pack/plugins/ml/public/application/util/dependency_cache.ts +++ b/x-pack/plugins/ml/public/application/util/dependency_cache.ts @@ -19,8 +19,9 @@ import type { ChromeRecentlyAccessed, IBasePath, } from 'kibana/public'; -import type { IndexPatternsContract, DataPublicPluginStart } from 'src/plugins/data/public'; +import type { DataPublicPluginStart } from 'src/plugins/data/public'; import type { SharePluginStart } from 'src/plugins/share/public'; +import type { DataViewsContract } from '../../../../../../src/plugins/data_views/public'; import type { SecurityPluginSetup } from '../../../../security/public'; import type { MapsStartApi } from '../../../../maps/public'; import type { DataVisualizerPluginStart } from '../../../../data_visualizer/public'; @@ -28,7 +29,7 @@ import type { DataVisualizerPluginStart } from '../../../../data_visualizer/publ export interface DependencyCache { timefilter: DataPublicPluginSetup['query']['timefilter'] | null; config: IUiSettingsClient | null; - indexPatterns: IndexPatternsContract | null; + indexPatterns: DataViewsContract | null; chrome: ChromeStart | null; docLinks: DocLinksStart | null; toastNotifications: ToastsStart | null; @@ -45,6 +46,7 @@ export interface DependencyCache { urlGenerators: SharePluginStart['urlGenerators'] | null; maps: MapsStartApi | null; dataVisualizer: DataVisualizerPluginStart | null; + dataViews: DataViewsContract | null; } const cache: DependencyCache = { @@ -67,6 +69,7 @@ const cache: DependencyCache = { urlGenerators: null, maps: null, dataVisualizer: null, + dataViews: null, }; export function setDependencyCache(deps: Partial<DependencyCache>) { @@ -88,6 +91,7 @@ export function setDependencyCache(deps: Partial<DependencyCache>) { cache.i18n = deps.i18n || null; cache.urlGenerators = deps.urlGenerators || null; cache.dataVisualizer = deps.dataVisualizer || null; + cache.dataViews = deps.dataViews || null; } export function getTimefilter() { @@ -208,6 +212,13 @@ export function getGetUrlGenerator() { return cache.urlGenerators.getUrlGenerator; } +export function getDataViews() { + if (cache.dataViews === null) { + throw new Error("dataViews hasn't been initialized"); + } + return cache.dataViews; +} + export function clearCache() { Object.keys(cache).forEach((k) => { cache[k as keyof DependencyCache] = null; diff --git a/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts b/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts index 440ac411e8ee7..0c50dc9efa343 100644 --- a/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts +++ b/x-pack/plugins/ml/public/application/util/field_types_utils.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { IFieldType, KBN_FIELD_TYPES } from '../../../../../../src/plugins/data/public'; +import { KBN_FIELD_TYPES } from '../../../../../../src/plugins/data/public'; +import { DataViewField } from '../../../../../../src/plugins/data_views/common'; import { ML_JOB_FIELD_TYPES } from '../../../common/constants/field_types'; import { kbnTypeToMLJobType, @@ -16,28 +17,34 @@ import { describe('ML - field type utils', () => { describe('kbnTypeToMLJobType', () => { test('returns correct ML_JOB_FIELD_TYPES for KBN_FIELD_TYPES', () => { - const field: IFieldType = { + // @ts-ignore reassigning missing properties + const field: DataViewField = { type: KBN_FIELD_TYPES.NUMBER, name: KBN_FIELD_TYPES.NUMBER, aggregatable: true, }; expect(kbnTypeToMLJobType(field)).toBe(ML_JOB_FIELD_TYPES.NUMBER); + // @ts-ignore reassigning read-only type field.type = KBN_FIELD_TYPES.DATE; expect(kbnTypeToMLJobType(field)).toBe(ML_JOB_FIELD_TYPES.DATE); + // @ts-ignore reassigning read-only type field.type = KBN_FIELD_TYPES.IP; expect(kbnTypeToMLJobType(field)).toBe(ML_JOB_FIELD_TYPES.IP); + // @ts-ignore reassigning read-only type field.type = KBN_FIELD_TYPES.BOOLEAN; expect(kbnTypeToMLJobType(field)).toBe(ML_JOB_FIELD_TYPES.BOOLEAN); + // @ts-ignore reassigning read-only type field.type = KBN_FIELD_TYPES.GEO_POINT; expect(kbnTypeToMLJobType(field)).toBe(ML_JOB_FIELD_TYPES.GEO_POINT); }); test('returns ML_JOB_FIELD_TYPES.KEYWORD for aggregatable KBN_FIELD_TYPES.STRING', () => { - const field: IFieldType = { + // @ts-ignore reassigning missing properties + const field: DataViewField = { type: KBN_FIELD_TYPES.STRING, name: KBN_FIELD_TYPES.STRING, aggregatable: true, @@ -46,7 +53,8 @@ describe('ML - field type utils', () => { }); test('returns ML_JOB_FIELD_TYPES.TEXT for non-aggregatable KBN_FIELD_TYPES.STRING', () => { - const field: IFieldType = { + // @ts-ignore reassigning missing properties + const field: DataViewField = { type: KBN_FIELD_TYPES.STRING, name: KBN_FIELD_TYPES.STRING, aggregatable: false, @@ -55,7 +63,8 @@ describe('ML - field type utils', () => { }); test('returns undefined for non-aggregatable "foo"', () => { - const field: IFieldType = { + // @ts-ignore reassigning missing properties + const field: DataViewField = { type: 'foo', name: 'foo', aggregatable: false, diff --git a/x-pack/plugins/ml/public/application/util/field_types_utils.ts b/x-pack/plugins/ml/public/application/util/field_types_utils.ts index 0cb21fec1862f..c02a1cbec56ec 100644 --- a/x-pack/plugins/ml/public/application/util/field_types_utils.ts +++ b/x-pack/plugins/ml/public/application/util/field_types_utils.ts @@ -8,12 +8,13 @@ import { i18n } from '@kbn/i18n'; import { ML_JOB_FIELD_TYPES } from '../../../common/constants/field_types'; -import { IFieldType, KBN_FIELD_TYPES } from '../../../../../../src/plugins/data/public'; +import { KBN_FIELD_TYPES } from '../../../../../../src/plugins/data/public'; +import { DataViewField } from '../../../../../../src/plugins/data_views/common'; // convert kibana types to ML Job types // this is needed because kibana types only have string and not text and keyword. // and we can't use ES_FIELD_TYPES because it has no NUMBER type -export function kbnTypeToMLJobType(field: IFieldType) { +export function kbnTypeToMLJobType(field: DataViewField) { // Return undefined if not one of the supported data visualizer field types. let type; switch (field.type) { diff --git a/x-pack/plugins/ml/public/application/util/index_utils.ts b/x-pack/plugins/ml/public/application/util/index_utils.ts index 9d705c8cd725f..b4f46d4df0cbb 100644 --- a/x-pack/plugins/ml/public/application/util/index_utils.ts +++ b/x-pack/plugins/ml/public/application/util/index_utils.ts @@ -6,33 +6,20 @@ */ import { i18n } from '@kbn/i18n'; -import { - IndexPattern, - IIndexPattern, - IndexPatternsContract, - Query, - IndexPatternAttributes, -} from '../../../../../../src/plugins/data/public'; -import { getToastNotifications, getSavedObjectsClient } from './dependency_cache'; -import { IndexPatternSavedObject, SavedSearchSavedObject } from '../../../common/types/kibana'; - -let indexPatternCache: IndexPatternSavedObject[] = []; +import type { Query } from '../../../../../../src/plugins/data/public'; +import type { DataView, DataViewsContract } from '../../../../../../src/plugins/data_views/public'; +import type { SavedSearchSavedObject } from '../../../common/types/kibana'; +import { getToastNotifications, getSavedObjectsClient, getDataViews } from './dependency_cache'; + +let indexPatternCache: DataView[] = []; let savedSearchesCache: SavedSearchSavedObject[] = []; -let indexPatternsContract: IndexPatternsContract | null = null; +let indexPatternsContract: DataViewsContract | null = null; -export function loadIndexPatterns(indexPatterns: IndexPatternsContract) { +export async function loadIndexPatterns(indexPatterns: DataViewsContract) { indexPatternsContract = indexPatterns; - const savedObjectsClient = getSavedObjectsClient(); - return savedObjectsClient - .find<IndexPatternAttributes>({ - type: 'index-pattern', - fields: ['id', 'title', 'type', 'fields'], - perPage: 10000, - }) - .then((response) => { - indexPatternCache = response.savedObjects; - return indexPatternCache; - }); + const dataViewsContract = getDataViews(); + indexPatternCache = await dataViewsContract.find('*', 10000); + return indexPatternCache; } export function loadSavedSearches() { @@ -63,20 +50,15 @@ export function getIndexPatternsContract() { } export function getIndexPatternNames() { - return indexPatternCache.map((i) => i.attributes && i.attributes.title); + return indexPatternCache.map((i) => i.title); } export function getIndexPatternIdFromName(name: string) { - for (let j = 0; j < indexPatternCache.length; j++) { - if (indexPatternCache[j].get('title') === name) { - return indexPatternCache[j].id; - } - } - return null; + return indexPatternCache.find((i) => i.title === name)?.id ?? null; } export interface IndexPatternAndSavedSearch { savedSearch: SavedSearchSavedObject | null; - indexPattern: IIndexPattern | null; + indexPattern: DataView | null; } export async function getIndexPatternAndSavedSearch(savedSearchId: string) { const resp: IndexPatternAndSavedSearch = { @@ -106,7 +88,7 @@ export function getQueryFromSavedSearch(savedSearch: SavedSearchSavedObject) { }; } -export function getIndexPatternById(id: string): Promise<IndexPattern> { +export function getIndexPatternById(id: string): Promise<DataView> { if (indexPatternsContract !== null) { if (id) { return indexPatternsContract.get(id); @@ -127,7 +109,7 @@ export function getSavedSearchById(id: string): SavedSearchSavedObject | undefin * an optional flag will trigger the display a notification at the top of the page * warning that the index is not time based */ -export function timeBasedIndexCheck(indexPattern: IndexPattern, showNotification = false) { +export function timeBasedIndexCheck(indexPattern: DataView, showNotification = false) { if (!indexPattern.isTimeBased()) { if (showNotification) { const toastNotifications = getToastNotifications(); diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx index 65d26b844e960..47be6065aa99b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx @@ -21,7 +21,7 @@ import { AnomalyChartsEmbeddableOutput, AnomalyChartsServices, } from '..'; -import type { IndexPattern } from '../../../../../../src/plugins/data/common'; +import type { DataView } from '../../../../../../src/plugins/data_views/common'; import { EmbeddableLoading } from '../common/components/embeddable_loading_fallback'; export const getDefaultExplorerChartsPanelTitle = (jobIds: JobId[]) => i18n.translate('xpack.ml.anomalyChartsEmbeddable.title', { @@ -66,7 +66,7 @@ export class AnomalyChartsEmbeddable extends Embeddable< const indices = new Set(jobs.map((j) => j.datafeed_config.indices).flat()); // Then find the index patterns assuming the index pattern title matches the index name - const indexPatterns: Record<string, IndexPattern> = {}; + const indexPatterns: Record<string, DataView> = {}; for (const indexName of indices) { const response = await indexPatternsService.find(`"${indexName}"`); diff --git a/x-pack/plugins/ml/public/embeddables/types.ts b/x-pack/plugins/ml/public/embeddables/types.ts index 7c93fb31e9a6c..bf23f397fe08c 100644 --- a/x-pack/plugins/ml/public/embeddables/types.ts +++ b/x-pack/plugins/ml/public/embeddables/types.ts @@ -27,7 +27,7 @@ import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, } from './constants'; import { MlResultsService } from '../application/services/results_service'; -import { IndexPattern } from '../../../../../src/plugins/data/common'; +import type { DataView } from '../../../../../src/plugins/data_views/common'; export interface AnomalySwimlaneEmbeddableCustomInput { jobIds: JobId[]; @@ -110,7 +110,7 @@ export type AnomalyChartsEmbeddableServices = [CoreStart, MlDependencies, Anomal export interface AnomalyChartsCustomOutput { entityFields?: EntityField[]; severity?: number; - indexPatterns?: IndexPattern[]; + indexPatterns?: DataView[]; } export type AnomalyChartsEmbeddableOutput = EmbeddableOutput & AnomalyChartsCustomOutput; export interface EditAnomalyChartsPanelContext { diff --git a/x-pack/plugins/ml/server/lib/data_views_utils.ts b/x-pack/plugins/ml/server/lib/data_views_utils.ts new file mode 100644 index 0000000000000..497404425eff8 --- /dev/null +++ b/x-pack/plugins/ml/server/lib/data_views_utils.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 type { IScopedClusterClient, SavedObjectsClientContract } from 'kibana/server'; + +import type { DataViewsService } from '../../../../../src/plugins/data_views/common'; +import type { PluginStart as DataViewsPluginStart } from '../../../../../src/plugins/data_views/server'; + +export type GetDataViewsService = () => Promise<DataViewsService>; + +export function getDataViewsServiceFactory( + getDataViews: () => DataViewsPluginStart | null, + savedObjectClient: SavedObjectsClientContract, + scopedClient: IScopedClusterClient +): GetDataViewsService { + const dataViews = getDataViews(); + if (dataViews === null) { + throw Error('data views service has not been initialized'); + } + + return () => dataViews.dataViewsServiceFactory(savedObjectClient, scopedClient.asInternalUser); +} diff --git a/x-pack/plugins/ml/server/lib/route_guard.ts b/x-pack/plugins/ml/server/lib/route_guard.ts index 1a066660d4ee0..b7b0568c10a31 100644 --- a/x-pack/plugins/ml/server/lib/route_guard.ts +++ b/x-pack/plugins/ml/server/lib/route_guard.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { +import type { KibanaRequest, KibanaResponseFactory, RequestHandlerContext, @@ -13,14 +13,17 @@ import { RequestHandler, SavedObjectsClientContract, } from 'kibana/server'; -import { SpacesPluginSetup } from '../../../spaces/server'; +import type { SpacesPluginSetup } from '../../../spaces/server'; import type { SecurityPluginSetup } from '../../../security/server'; import { jobSavedObjectServiceFactory, JobSavedObjectService } from '../saved_objects'; -import { MlLicense } from '../../common/license'; +import type { MlLicense } from '../../common/license'; import { MlClient, getMlClient } from '../lib/ml_client'; import type { AlertingApiRequestHandlerContext } from '../../../alerting/server'; +import type { PluginStart as DataViewsPluginStart } from '../../../../../src/plugins/data_views/server'; +import type { DataViewsService } from '../../../../../src/plugins/data_views/common'; +import { getDataViewsServiceFactory } from './data_views_utils'; type MLRequestHandlerContext = RequestHandlerContext & { alerting?: AlertingApiRequestHandlerContext; @@ -33,10 +36,12 @@ type Handler<P = unknown, Q = unknown, B = unknown> = (handlerParams: { context: MLRequestHandlerContext; jobSavedObjectService: JobSavedObjectService; mlClient: MlClient; + getDataViewsService(): Promise<DataViewsService>; }) => ReturnType<RequestHandler<P, Q, B>>; type GetMlSavedObjectClient = (request: KibanaRequest) => SavedObjectsClientContract | null; type GetInternalSavedObjectClient = () => SavedObjectsClientContract | null; +type GetDataViews = () => DataViewsPluginStart | null; export class RouteGuard { private _mlLicense: MlLicense; @@ -45,6 +50,7 @@ export class RouteGuard { private _spacesPlugin: SpacesPluginSetup | undefined; private _authorization: SecurityPluginSetup['authz'] | undefined; private _isMlReady: () => Promise<void>; + private _getDataViews: GetDataViews; constructor( mlLicense: MlLicense, @@ -52,7 +58,8 @@ export class RouteGuard { getInternalSavedObject: GetInternalSavedObjectClient, spacesPlugin: SpacesPluginSetup | undefined, authorization: SecurityPluginSetup['authz'] | undefined, - isMlReady: () => Promise<void> + isMlReady: () => Promise<void>, + getDataViews: GetDataViews ) { this._mlLicense = mlLicense; this._getMlSavedObjectClient = getSavedObject; @@ -60,6 +67,7 @@ export class RouteGuard { this._spacesPlugin = spacesPlugin; this._authorization = authorization; this._isMlReady = isMlReady; + this._getDataViews = getDataViews; } public fullLicenseAPIGuard<P, Q, B>(handler: Handler<P, Q, B>) { @@ -79,6 +87,7 @@ export class RouteGuard { return response.forbidden(); } + const client = context.core.elasticsearch.client; const mlSavedObjectClient = this._getMlSavedObjectClient(request); const internalSavedObjectsClient = this._getInternalSavedObjectClient(); if (mlSavedObjectClient === null || internalSavedObjectsClient === null) { @@ -94,7 +103,6 @@ export class RouteGuard { this._authorization, this._isMlReady ); - const client = context.core.elasticsearch.client; return handler({ client, @@ -103,6 +111,11 @@ export class RouteGuard { context, jobSavedObjectService, mlClient: getMlClient(client, jobSavedObjectService), + getDataViewsService: getDataViewsServiceFactory( + this._getDataViews, + context.core.savedObjects.client, + client + ), }); }; } diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts index 15b4cfa5be8b1..568be4197baf8 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts @@ -5,29 +5,19 @@ * 2.0. */ -import { SavedObjectsClientContract } from 'kibana/server'; -import { IndexPatternAttributes } from 'src/plugins/data/server'; +import { DataViewsService } from '../../../../../../src/plugins/data_views/common'; export class IndexPatternHandler { - constructor(private savedObjectsClient: SavedObjectsClientContract) {} + constructor(private dataViewService: DataViewsService) {} // returns a id based on an index pattern name async getIndexPatternId(indexName: string) { - const response = await this.savedObjectsClient.find<IndexPatternAttributes>({ - type: 'index-pattern', - perPage: 10, - search: `"${indexName}"`, - searchFields: ['title'], - fields: ['title'], - }); - - const ip = response.saved_objects.find( - (obj) => obj.attributes.title.toLowerCase() === indexName.toLowerCase() + const dv = (await this.dataViewService.find(indexName)).find( + ({ title }) => title === indexName ); - - return ip?.id; + return dv?.id; } async deleteIndexPatternById(indexId: string) { - return await this.savedObjectsClient.delete('index-pattern', indexId); + return await this.dataViewService.delete(indexId); } } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts index 8ddb805af2033..e853d5de5899d 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts @@ -5,11 +5,16 @@ * 2.0. */ -import { SavedObjectsClientContract, KibanaRequest, IScopedClusterClient } from 'kibana/server'; -import { Module } from '../../../common/types/modules'; +import type { + SavedObjectsClientContract, + KibanaRequest, + IScopedClusterClient, +} from 'kibana/server'; +import type { DataViewsService } from '../../../../../../src/plugins/data_views/common'; +import type { Module } from '../../../common/types/modules'; import { DataRecognizer } from '../data_recognizer'; import type { MlClient } from '../../lib/ml_client'; -import { JobSavedObjectService } from '../../saved_objects'; +import type { JobSavedObjectService } from '../../saved_objects'; const callAs = () => Promise.resolve({ body: {} }); @@ -28,6 +33,7 @@ describe('ML - data recognizer', () => { find: jest.fn(), bulkCreate: jest.fn(), } as unknown as SavedObjectsClientContract, + { find: jest.fn() } as unknown as DataViewsService, {} as JobSavedObjectService, { headers: { authorization: '' } } as KibanaRequest ); diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index f9c609803217e..711ec0d458f27 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -8,17 +8,21 @@ import fs from 'fs'; import Boom from '@hapi/boom'; import numeral from '@elastic/numeral'; -import { KibanaRequest, IScopedClusterClient, SavedObjectsClientContract } from 'kibana/server'; +import type { + KibanaRequest, + IScopedClusterClient, + SavedObjectsClientContract, +} from 'kibana/server'; import moment from 'moment'; -import { IndexPatternAttributes } from 'src/plugins/data/server'; import { merge } from 'lodash'; -import { AnalysisLimits } from '../../../common/types/anomaly_detection_jobs'; +import type { DataViewsService } from '../../../../../../src/plugins/data_views/common'; +import type { AnalysisLimits } from '../../../common/types/anomaly_detection_jobs'; import { getAuthorizationHeader } from '../../lib/request_authorization'; -import { MlInfoResponse } from '../../../common/types/ml_server_info'; +import type { MlInfoResponse } from '../../../common/types/ml_server_info'; import type { MlClient } from '../../lib/ml_client'; import { ML_MODULE_SAVED_OBJECT_TYPE } from '../../../common/types/saved_objects'; -import { +import type { KibanaObjects, KibanaObjectConfig, ModuleDatafeed, @@ -35,8 +39,8 @@ import { DataRecognizerConfigResponse, GeneralDatafeedsOverride, JobSpecificOverride, - isGeneralJobOverride, } from '../../../common/types/modules'; +import { isGeneralJobOverride } from '../../../common/types/modules'; import { getLatestDataOrBucketTimestamp, prefixDatafeedId, @@ -47,10 +51,10 @@ import { calculateModelMemoryLimitProvider } from '../calculate_model_memory_lim import { fieldsServiceProvider } from '../fields_service'; import { jobServiceProvider } from '../job_service'; import { resultsServiceProvider } from '../results_service'; -import { JobExistResult, JobStat } from '../../../common/types/data_recognizer'; -import { MlJobsStatsResponse } from '../../../common/types/job_service'; -import { Datafeed } from '../../../common/types/anomaly_detection_jobs'; -import { JobSavedObjectService } from '../../saved_objects'; +import type { JobExistResult, JobStat } from '../../../common/types/data_recognizer'; +import type { MlJobsStatsResponse } from '../../../common/types/job_service'; +import type { Datafeed } from '../../../common/types/anomaly_detection_jobs'; +import type { JobSavedObjectService } from '../../saved_objects'; import { isDefined } from '../../../common/types/guards'; import { isPopulatedObject } from '../../../common/util/object_utils'; @@ -110,6 +114,7 @@ export class DataRecognizer { private _mlClient: MlClient; private _savedObjectsClient: SavedObjectsClientContract; private _jobSavedObjectService: JobSavedObjectService; + private _dataViewsService: DataViewsService; private _request: KibanaRequest; private _authorizationHeader: object; @@ -130,12 +135,14 @@ export class DataRecognizer { mlClusterClient: IScopedClusterClient, mlClient: MlClient, savedObjectsClient: SavedObjectsClientContract, + dataViewsService: DataViewsService, jobSavedObjectService: JobSavedObjectService, request: KibanaRequest ) { this._client = mlClusterClient; this._mlClient = mlClient; this._savedObjectsClient = savedObjectsClient; + this._dataViewsService = dataViewsService; this._jobSavedObjectService = jobSavedObjectService; this._request = request; this._authorizationHeader = getAuthorizationHeader(request); @@ -615,22 +622,11 @@ export class DataRecognizer { return results; } - private async _loadIndexPatterns() { - return await this._savedObjectsClient.find<IndexPatternAttributes>({ - type: 'index-pattern', - perPage: 1000, - }); - } - // returns a id based on an index pattern name - private async _getIndexPatternId(name: string) { + private async _getIndexPatternId(name: string): Promise<string | undefined> { try { - const indexPatterns = await this._loadIndexPatterns(); - if (indexPatterns === undefined || indexPatterns.saved_objects === undefined) { - return; - } - const ip = indexPatterns.saved_objects.find((i) => i.attributes.title === name); - return ip !== undefined ? ip.id : undefined; + const dataViews = await this._dataViewsService.find(name); + return dataViews.find((d) => d.title === name)?.id; } catch (error) { mlLog.warn(`Error loading index patterns, ${error}`); return; @@ -1387,3 +1383,21 @@ export class DataRecognizer { } } } + +export function dataRecognizerFactory( + client: IScopedClusterClient, + mlClient: MlClient, + savedObjectsClient: SavedObjectsClientContract, + dataViewsService: DataViewsService, + jobSavedObjectService: JobSavedObjectService, + request: KibanaRequest +) { + return new DataRecognizer( + client, + mlClient, + savedObjectsClient, + dataViewsService, + jobSavedObjectService, + request + ); +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/index.ts b/x-pack/plugins/ml/server/models/data_recognizer/index.ts index 27c45726ae249..fbddf17a50ede 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/index.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { DataRecognizer, RecognizeResult } from './data_recognizer'; +export { DataRecognizer, RecognizeResult, dataRecognizerFactory } from './data_recognizer'; diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/data_view_rollup_cloudwatch.json b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/data_view_rollup_cloudwatch.json new file mode 100644 index 0000000000000..a6aeb81431532 --- /dev/null +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/data_view_rollup_cloudwatch.json @@ -0,0 +1,151 @@ +[ + { + "id": "d6ac99b0-2777-11ec-8e1c-aba6d0767aaa", + "title": "cloud_roll_index", + "fieldFormatMap": {}, + "typeMeta": { + "params": { + "rollup_index": "cloud_roll_index" + }, + "aggs": { + "date_histogram": { + "@timestamp": { + "agg": "date_histogram", + "fixed_interval": "5m", + "time_zone": "UTC" + } + } + } + }, + "fields": [ + { + "count": 0, + "name": "_source", + "type": "_source", + "esTypes": [ + "_source" + ], + "scripted": false, + "searchable": false, + "aggregatable": false, + "readFromDocValues": false + }, + { + "count": 0, + "name": "_id", + "type": "string", + "esTypes": [ + "_id" + ], + "scripted": false, + "searchable": true, + "aggregatable": false, + "readFromDocValues": false + }, + { + "count": 0, + "name": "_type", + "type": "string", + "scripted": false, + "searchable": false, + "aggregatable": false, + "readFromDocValues": false + }, + { + "count": 0, + "name": "_index", + "type": "string", + "esTypes": [ + "_index" + ], + "scripted": false, + "searchable": true, + "aggregatable": true, + "readFromDocValues": false + }, + { + "count": 0, + "name": "_score", + "type": "number", + "scripted": false, + "searchable": false, + "aggregatable": false, + "readFromDocValues": false + }, + { + "count": 0, + "name": "@timestamp", + "type": "date", + "esTypes": [ + "date" + ], + "scripted": false, + "searchable": true, + "aggregatable": true, + "readFromDocValues": true + } + ], + "timeFieldName": "@timestamp", + "type": "rollup", + "metaFields": [ + "_source", + "_id", + "_type", + "_index", + "_score" + ], + "version": "WzY5NjEsNF0=", + "originalSavedObjectBody": { + "fieldAttrs": "{}", + "title": "cloud_roll_index", + "timeFieldName": "@timestamp", + "fields": "[]", + "type": "rollup", + "typeMeta": "{\"params\":{\"rollup_index\":\"cloud_roll_index\"},\"aggs\":{\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"fixed_interval\":\"5m\",\"time_zone\":\"UTC\"}}}}", + "runtimeFieldMap": "{}" + }, + "shortDotsEnable": false, + "fieldFormats": { + "fieldFormats": {}, + "defaultMap": { + "ip": { + "id": "ip", + "params": {} + }, + "date": { + "id": "date", + "params": {} + }, + "date_nanos": { + "id": "date_nanos", + "params": {}, + "es": true + }, + "number": { + "id": "number", + "params": {} + }, + "boolean": { + "id": "boolean", + "params": {} + }, + "histogram": { + "id": "histogram", + "params": {} + }, + "_source": { + "id": "_source", + "params": {} + }, + "_default_": { + "id": "string", + "params": {} + } + }, + "metaParamsOptions": {} + }, + "fieldAttrs": {}, + "runtimeFieldMap": {}, + "allowNoIndex": false + } +] diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json deleted file mode 100644 index 9e2af76264231..0000000000000 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "page": 1, - "per_page": 1000, - "total": 4, - "saved_objects": [ - { - "type": "index-pattern", - "id": "be0eebe0-65ac-11e9-aa86-0793be5f3670", - "attributes": { - "title": "farequote-*" - }, - "references": [], - "migrationVersion": { - "index-pattern": "6.5.0" - }, - "updated_at": "2019-04-23T09:47:02.203Z", - "version": "WzcsMV0=" - }, - { - "type": "index-pattern", - "id": "be14ceb0-66b1-11e9-91c9-ffa52374d341", - "attributes": { - "typeMeta": "{\"params\":{\"rollup_index\":\"cloud_roll_index\"},\"aggs\":{\"histogram\":{\"NetworkOut\":{\"agg\":\"histogram\",\"interval\":5},\"CPUUtilization\":{\"agg\":\"histogram\",\"interval\":5},\"NetworkIn\":{\"agg\":\"histogram\",\"interval\":5}},\"avg\":{\"NetworkOut\":{\"agg\":\"avg\"},\"CPUUtilization\":{\"agg\":\"avg\"},\"NetworkIn\":{\"agg\":\"avg\"},\"DiskReadBytes\":{\"agg\":\"avg\"}},\"min\":{\"NetworkOut\":{\"agg\":\"min\"},\"NetworkIn\":{\"agg\":\"min\"}},\"value_count\":{\"NetworkOut\":{\"agg\":\"value_count\"},\"DiskReadBytes\":{\"agg\":\"value_count\"},\"CPUUtilization\":{\"agg\":\"value_count\"},\"NetworkIn\":{\"agg\":\"value_count\"}},\"max\":{\"CPUUtilization\":{\"agg\":\"max\"},\"DiskReadBytes\":{\"agg\":\"max\"}},\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"delay\":\"1d\",\"fixed_interval\":\"5m\",\"time_zone\":\"UTC\"}},\"terms\":{\"instance\":{\"agg\":\"terms\"},\"sourcetype.keyword\":{\"agg\":\"terms\"},\"region\":{\"agg\":\"terms\"}},\"sum\":{\"DiskReadBytes\":{\"agg\":\"sum\"},\"NetworkOut\":{\"agg\":\"sum\"}}}}", - "title": "cloud_roll_index", - "type": "rollup" - }, - "references": [], - "migrationVersion": { - "index-pattern": "6.5.0" - }, - "updated_at": "2019-04-24T16:55:20.550Z", - "version": "Wzc0LDJd" - } - ] -} diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts index b838165826da1..a25b3183362b3 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { estypes } from '@elastic/elasticsearch'; -import { IScopedClusterClient } from 'kibana/server'; import { cloneDeep } from 'lodash'; -import { SavedObjectsClientContract } from 'kibana/server'; -import { Field, FieldId, NewJobCaps, RollupFields } from '../../../../common/types/fields'; +import { estypes } from '@elastic/elasticsearch'; +import type { IScopedClusterClient } from 'kibana/server'; +import type { Field, FieldId, NewJobCaps, RollupFields } from '../../../../common/types/fields'; import { ES_FIELD_TYPES } from '../../../../../../../src/plugins/data/common'; +import type { DataViewsService } from '../../../../../../../src/plugins/data_views/common'; import { combineFieldsAndAggs } from '../../../../common/util/fields_utils'; import { rollupServiceProvider } from './rollup'; import { aggregations, mlOnlyAggregations } from '../../../../common/constants/aggregation_types'; @@ -38,27 +38,27 @@ export function fieldServiceProvider( indexPattern: string, isRollup: boolean, client: IScopedClusterClient, - savedObjectsClient: SavedObjectsClientContract + dataViewsService: DataViewsService ) { - return new FieldsService(indexPattern, isRollup, client, savedObjectsClient); + return new FieldsService(indexPattern, isRollup, client, dataViewsService); } class FieldsService { private _indexPattern: string; private _isRollup: boolean; private _mlClusterClient: IScopedClusterClient; - private _savedObjectsClient: SavedObjectsClientContract; + private _dataViewsService: DataViewsService; constructor( indexPattern: string, isRollup: boolean, client: IScopedClusterClient, - savedObjectsClient: SavedObjectsClientContract + dataViewsService: DataViewsService ) { this._indexPattern = indexPattern; this._isRollup = isRollup; this._mlClusterClient = client; - this._savedObjectsClient = savedObjectsClient; + this._dataViewsService = dataViewsService; } private async loadFieldCaps(): Promise<any> { @@ -111,7 +111,7 @@ class FieldsService { const rollupService = await rollupServiceProvider( this._indexPattern, this._mlClusterClient, - this._savedObjectsClient + this._dataViewsService ); const rollupConfigs: estypes.RollupGetRollupCapabilitiesRollupCapabilitySummary[] | null = await rollupService.getRollupJobs(); diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts index 3eb2ba5bbaced..c0f270f1df96c 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts @@ -10,7 +10,7 @@ import { newJobCapsProvider } from './index'; import farequoteFieldCaps from './__mocks__/responses/farequote_field_caps.json'; import cloudwatchFieldCaps from './__mocks__/responses/cloudwatch_field_caps.json'; import rollupCaps from './__mocks__/responses/rollup_caps.json'; -import kibanaSavedObjects from './__mocks__/responses/kibana_saved_objects.json'; +import dataView from './__mocks__/responses/data_view_rollup_cloudwatch.json'; import farequoteJobCaps from './__mocks__/results/farequote_job_caps.json'; import farequoteJobCapsEmpty from './__mocks__/results/farequote_job_caps_empty.json'; @@ -19,7 +19,7 @@ import cloudwatchJobCaps from './__mocks__/results/cloudwatch_rollup_job_caps.js describe('job_service - job_caps', () => { let mlClusterClientNonRollupMock: any; let mlClusterClientRollupMock: any; - let savedObjectsClientMock: any; + let dataViews: any; beforeEach(() => { const asNonRollupMock = { @@ -41,9 +41,9 @@ describe('job_service - job_caps', () => { asInternalUser: callAsRollupMock, }; - savedObjectsClientMock = { + dataViews = { async find() { - return Promise.resolve(kibanaSavedObjects); + return Promise.resolve(dataView); }, }; }); @@ -53,7 +53,7 @@ describe('job_service - job_caps', () => { const indexPattern = 'farequote-*'; const isRollup = false; const { newJobCaps } = newJobCapsProvider(mlClusterClientNonRollupMock); - const response = await newJobCaps(indexPattern, isRollup, savedObjectsClientMock); + const response = await newJobCaps(indexPattern, isRollup, dataViews); expect(response).toEqual(farequoteJobCaps); }); @@ -61,7 +61,7 @@ describe('job_service - job_caps', () => { const indexPattern = 'farequote-*'; const isRollup = true; const { newJobCaps } = newJobCapsProvider(mlClusterClientNonRollupMock); - const response = await newJobCaps(indexPattern, isRollup, savedObjectsClientMock); + const response = await newJobCaps(indexPattern, isRollup, dataViews); expect(response).toEqual(farequoteJobCapsEmpty); }); }); @@ -71,7 +71,7 @@ describe('job_service - job_caps', () => { const indexPattern = 'cloud_roll_index'; const isRollup = true; const { newJobCaps } = newJobCapsProvider(mlClusterClientRollupMock); - const response = await newJobCaps(indexPattern, isRollup, savedObjectsClientMock); + const response = await newJobCaps(indexPattern, isRollup, dataViews); expect(response).toEqual(cloudwatchJobCaps); }); @@ -79,7 +79,7 @@ describe('job_service - job_caps', () => { const indexPattern = 'cloud_roll_index'; const isRollup = false; const { newJobCaps } = newJobCapsProvider(mlClusterClientRollupMock); - const response = await newJobCaps(indexPattern, isRollup, savedObjectsClientMock); + const response = await newJobCaps(indexPattern, isRollup, dataViews); expect(response).not.toEqual(cloudwatchJobCaps); }); }); diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts index 6444f9ae3f61a..bab4fb31aa1a9 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts @@ -5,18 +5,19 @@ * 2.0. */ -import { IScopedClusterClient, SavedObjectsClientContract } from 'kibana/server'; +import type { IScopedClusterClient } from 'kibana/server'; +import type { DataViewsService } from '../../../../../../../src/plugins/data_views/common'; +import type { Aggregation, Field, NewJobCapsResponse } from '../../../../common/types/fields'; import { _DOC_COUNT } from '../../../../common/constants/field_types'; -import { Aggregation, Field, NewJobCapsResponse } from '../../../../common/types/fields'; import { fieldServiceProvider } from './field_service'; export function newJobCapsProvider(client: IScopedClusterClient) { async function newJobCaps( indexPattern: string, isRollup: boolean = false, - savedObjectsClient: SavedObjectsClientContract + dataViewsService: DataViewsService ): Promise<NewJobCapsResponse> { - const fieldService = fieldServiceProvider(indexPattern, isRollup, client, savedObjectsClient); + const fieldService = fieldServiceProvider(indexPattern, isRollup, client, dataViewsService); const { aggs, fields } = await fieldService.getData(); convertForStringify(aggs, fields); diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts index 72408b7f9c534..87504a1bc0e10 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts @@ -6,11 +6,12 @@ */ import { estypes } from '@elastic/elasticsearch'; -import { IScopedClusterClient } from 'kibana/server'; -import { SavedObject } from 'kibana/server'; -import { IndexPatternAttributes } from 'src/plugins/data/server'; -import { SavedObjectsClientContract } from 'kibana/server'; -import { RollupFields } from '../../../../common/types/fields'; +import type { IScopedClusterClient } from 'kibana/server'; +import type { + DataViewsService, + DataView, +} from '../../../../../../../src/plugins/data_views/common'; +import type { RollupFields } from '../../../../common/types/fields'; export interface RollupJob { job_id: string; @@ -22,17 +23,19 @@ export interface RollupJob { export async function rollupServiceProvider( indexPattern: string, { asCurrentUser }: IScopedClusterClient, - savedObjectsClient: SavedObjectsClientContract + dataViewsService: DataViewsService ) { - const rollupIndexPatternObject = await loadRollupIndexPattern(indexPattern, savedObjectsClient); + const rollupIndexPatternObject = await loadRollupIndexPattern(indexPattern, dataViewsService); let jobIndexPatterns: string[] = [indexPattern]; async function getRollupJobs(): Promise< estypes.RollupGetRollupCapabilitiesRollupCapabilitySummary[] | null > { - if (rollupIndexPatternObject !== null) { - const parsedTypeMetaData = JSON.parse(rollupIndexPatternObject.attributes.typeMeta!); - const rollUpIndex: string = parsedTypeMetaData.params.rollup_index; + if ( + rollupIndexPatternObject !== null && + rollupIndexPatternObject.typeMeta?.params !== undefined + ) { + const rollUpIndex: string = rollupIndexPatternObject.typeMeta.params.rollup_index; const { body: rollupCaps } = await asCurrentUser.rollup.getRollupIndexCaps({ index: rollUpIndex, }); @@ -60,21 +63,12 @@ export async function rollupServiceProvider( async function loadRollupIndexPattern( indexPattern: string, - savedObjectsClient: SavedObjectsClientContract -): Promise<SavedObject<IndexPatternAttributes> | null> { - const resp = await savedObjectsClient.find<IndexPatternAttributes>({ - type: 'index-pattern', - fields: ['title', 'type', 'typeMeta'], - perPage: 1000, - }); - - const obj = resp.saved_objects.find( - (r) => - r.attributes && - r.attributes.type === 'rollup' && - r.attributes.title === indexPattern && - r.attributes.typeMeta !== undefined + dataViewsService: DataViewsService +): Promise<DataView | null> { + const resp = await dataViewsService.find('*', 10000); + const obj = resp.find( + (dv) => dv.type === 'rollup' && dv.title === indexPattern && dv.typeMeta !== undefined ); - return obj || null; + return obj ?? null; } diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 3876193cfbe39..efa61593655ac 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { +import type { CoreSetup, CoreStart, Plugin, @@ -21,10 +21,11 @@ import { } from 'kibana/server'; import type { SecurityPluginSetup } from '../../security/server'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; -import { PluginsSetup, PluginsStart, RouteInitialization } from './types'; -import { SpacesPluginSetup } from '../../spaces/server'; +import type { PluginStart as DataViewsPluginStart } from '../../../../src/plugins/data_views/server'; +import type { PluginsSetup, PluginsStart, RouteInitialization } from './types'; +import type { SpacesPluginSetup } from '../../spaces/server'; import { PLUGIN_ID } from '../common/constants/app'; -import { MlCapabilities } from '../common/types/capabilities'; +import type { MlCapabilities } from '../common/types/capabilities'; import { initMlServerLog } from './lib/log'; import { initSampleDataSets } from './lib/sample_data_sets'; @@ -78,6 +79,7 @@ export class MlServerPlugin private savedObjectsStart: SavedObjectsServiceStart | null = null; private spacesPlugin: SpacesPluginSetup | undefined; private security: SecurityPluginSetup | undefined; + private dataViews: DataViewsPluginStart | null = null; private isMlReady: Promise<void>; private setMlReady: () => void = () => {}; private readonly kibanaIndexConfig: SharedGlobalConfig; @@ -156,7 +158,8 @@ export class MlServerPlugin getInternalSavedObjectsClient, plugins.spaces, plugins.security?.authz, - () => this.isMlReady + () => this.isMlReady, + () => this.dataViews ), mlLicense: this.mlLicense, }; @@ -173,6 +176,13 @@ export class MlServerPlugin ? () => coreSetup.getStartServices().then(([, { spaces }]) => spaces!) : undefined; + const getDataViews = () => { + if (this.dataViews === null) { + throw Error('Data views plugin not initialized'); + } + return this.dataViews; + }; + annotationRoutes(routeInit, plugins.security); calendars(routeInit); dataFeedRoutes(routeInit); @@ -211,6 +221,7 @@ export class MlServerPlugin () => getInternalSavedObjectsClient(), () => this.uiSettings, () => this.fieldsFormat, + getDataViews, () => this.isMlReady ); @@ -236,6 +247,7 @@ export class MlServerPlugin this.capabilities = coreStart.capabilities; this.clusterClient = coreStart.elasticsearch.client; this.savedObjectsStart = coreStart.savedObjects; + this.dataViews = plugins.dataViews; // check whether the job saved objects exist // and create them if needed. diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index bedc70566a62f..bbfcc0fd5e500 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { RequestHandlerContext, IScopedClusterClient } from 'kibana/server'; +import type { IScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { analyticsAuditMessagesProvider } from '../models/data_frame_analytics/analytics_audit_messages'; -import { RouteInitialization } from '../types'; +import type { RouteInitialization } from '../types'; import { JOB_MAP_NODE_TYPES } from '../../common/constants/data_frame_analytics'; -import { Field, Aggregation } from '../../common/types/fields'; +import type { Field, Aggregation } from '../../common/types/fields'; import { dataAnalyticsJobConfigSchema, dataAnalyticsJobUpdateSchema, @@ -25,22 +25,26 @@ import { analyticsNewJobCapsParamsSchema, analyticsNewJobCapsQuerySchema, } from './schemas/data_analytics_schema'; -import { GetAnalyticsMapArgs, ExtendAnalyticsMapArgs } from '../models/data_frame_analytics/types'; +import type { + GetAnalyticsMapArgs, + ExtendAnalyticsMapArgs, +} from '../models/data_frame_analytics/types'; import { IndexPatternHandler } from '../models/data_frame_analytics/index_patterns'; import { AnalyticsManager } from '../models/data_frame_analytics/analytics_manager'; import { validateAnalyticsJob } from '../models/data_frame_analytics/validation'; import { fieldServiceProvider } from '../models/job_service/new_job_caps/field_service'; -import { DeleteDataFrameAnalyticsWithIndexStatus } from '../../common/types/data_frame_analytics'; +import type { DeleteDataFrameAnalyticsWithIndexStatus } from '../../common/types/data_frame_analytics'; import { getAuthorizationHeader } from '../lib/request_authorization'; import type { MlClient } from '../lib/ml_client'; +import type { DataViewsService } from '../../../../../src/plugins/data_views/common'; -function getIndexPatternId(context: RequestHandlerContext, patternName: string) { - const iph = new IndexPatternHandler(context.core.savedObjects.client); +function getIndexPatternId(dataViewsService: DataViewsService, patternName: string) { + const iph = new IndexPatternHandler(dataViewsService); return iph.getIndexPatternId(patternName); } -function deleteDestIndexPatternById(context: RequestHandlerContext, indexPatternId: string) { - const iph = new IndexPatternHandler(context.core.savedObjects.client); +function deleteDestIndexPatternById(dataViewsService: DataViewsService, indexPatternId: string) { + const iph = new IndexPatternHandler(dataViewsService); return iph.deleteIndexPatternById(indexPatternId); } @@ -374,86 +378,89 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout tags: ['access:ml:canDeleteDataFrameAnalytics'], }, }, - routeGuard.fullLicenseAPIGuard(async ({ mlClient, client, request, response, context }) => { - try { - const { analyticsId } = request.params; - const { deleteDestIndex, deleteDestIndexPattern } = request.query; - let destinationIndex: string | undefined; - const analyticsJobDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false }; - const destIndexDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false }; - const destIndexPatternDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { - success: false, - }; - + routeGuard.fullLicenseAPIGuard( + async ({ mlClient, client, request, response, getDataViewsService }) => { try { - // Check if analyticsId is valid and get destination index - const { body } = await mlClient.getDataFrameAnalytics({ - id: analyticsId, - }); - if (Array.isArray(body.data_frame_analytics) && body.data_frame_analytics.length > 0) { - destinationIndex = body.data_frame_analytics[0].dest.index; + const { analyticsId } = request.params; + const { deleteDestIndex, deleteDestIndexPattern } = request.query; + let destinationIndex: string | undefined; + const analyticsJobDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false }; + const destIndexDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false }; + const destIndexPatternDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { + success: false, + }; + + try { + // Check if analyticsId is valid and get destination index + const { body } = await mlClient.getDataFrameAnalytics({ + id: analyticsId, + }); + if (Array.isArray(body.data_frame_analytics) && body.data_frame_analytics.length > 0) { + destinationIndex = body.data_frame_analytics[0].dest.index; + } + } catch (e) { + // exist early if the job doesn't exist + return response.customError(wrapError(e)); } - } catch (e) { - // exist early if the job doesn't exist - return response.customError(wrapError(e)); - } - if (deleteDestIndex || deleteDestIndexPattern) { - // If user checks box to delete the destinationIndex associated with the job - if (destinationIndex && deleteDestIndex) { - // Verify if user has privilege to delete the destination index - const userCanDeleteDestIndex = await userCanDeleteIndex(client, destinationIndex); - // If user does have privilege to delete the index, then delete the index - if (userCanDeleteDestIndex) { - try { - await client.asCurrentUser.indices.delete({ - index: destinationIndex, - }); - destIndexDeleted.success = true; - } catch ({ body }) { - destIndexDeleted.error = body; + if (deleteDestIndex || deleteDestIndexPattern) { + // If user checks box to delete the destinationIndex associated with the job + if (destinationIndex && deleteDestIndex) { + // Verify if user has privilege to delete the destination index + const userCanDeleteDestIndex = await userCanDeleteIndex(client, destinationIndex); + // If user does have privilege to delete the index, then delete the index + if (userCanDeleteDestIndex) { + try { + await client.asCurrentUser.indices.delete({ + index: destinationIndex, + }); + destIndexDeleted.success = true; + } catch ({ body }) { + destIndexDeleted.error = body; + } + } else { + return response.forbidden(); } - } else { - return response.forbidden(); } - } - // Delete the index pattern if there's an index pattern that matches the name of dest index - if (destinationIndex && deleteDestIndexPattern) { - try { - const indexPatternId = await getIndexPatternId(context, destinationIndex); - if (indexPatternId) { - await deleteDestIndexPatternById(context, indexPatternId); + // Delete the index pattern if there's an index pattern that matches the name of dest index + if (destinationIndex && deleteDestIndexPattern) { + try { + const dataViewsService = await getDataViewsService(); + const indexPatternId = await getIndexPatternId(dataViewsService, destinationIndex); + if (indexPatternId) { + await deleteDestIndexPatternById(dataViewsService, indexPatternId); + } + destIndexPatternDeleted.success = true; + } catch (deleteDestIndexPatternError) { + destIndexPatternDeleted.error = deleteDestIndexPatternError; } - destIndexPatternDeleted.success = true; - } catch (deleteDestIndexPatternError) { - destIndexPatternDeleted.error = deleteDestIndexPatternError; } } - } - // Grab the target index from the data frame analytics job id - // Delete the data frame analytics + // Grab the target index from the data frame analytics job id + // Delete the data frame analytics - try { - await mlClient.deleteDataFrameAnalytics({ - id: analyticsId, + try { + await mlClient.deleteDataFrameAnalytics({ + id: analyticsId, + }); + analyticsJobDeleted.success = true; + } catch ({ body }) { + analyticsJobDeleted.error = body; + } + const results = { + analyticsJobDeleted, + destIndexDeleted, + destIndexPatternDeleted, + }; + return response.ok({ + body: results, }); - analyticsJobDeleted.success = true; - } catch ({ body }) { - analyticsJobDeleted.error = body; + } catch (e) { + return response.customError(wrapError(e)); } - const results = { - analyticsJobDeleted, - destIndexDeleted, - destIndexPatternDeleted, - }; - return response.ok({ - body: results, - }); - } catch (e) { - return response.customError(wrapError(e)); } - }) + ) ); /** @@ -716,17 +723,12 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout tags: ['access:ml:canGetJobs'], }, }, - routeGuard.fullLicenseAPIGuard(async ({ client, request, response, context }) => { + routeGuard.fullLicenseAPIGuard(async ({ client, request, response, getDataViewsService }) => { try { const { indexPattern } = request.params; const isRollup = request.query?.rollup === 'true'; - const savedObjectsClient = context.core.savedObjects.client; - const fieldService = fieldServiceProvider( - indexPattern, - isRollup, - client, - savedObjectsClient - ); + const dataViewsService = await getDataViewsService(); + const fieldService = fieldServiceProvider(indexPattern, isRollup, client, dataViewsService); const { fields, aggs } = await fieldService.getData(true); convertForStringify(aggs, fields); diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index da115a224d19e..15b0b4449590c 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -8,7 +8,7 @@ import { estypes } from '@elastic/elasticsearch'; import { schema } from '@kbn/config-schema'; import { wrapError } from '../client/error_wrapper'; -import { RouteInitialization } from '../types'; +import type { RouteInitialization } from '../types'; import { categorizationFieldExamplesSchema, basicChartSchema, @@ -32,7 +32,7 @@ import { jobIdSchema } from './schemas/anomaly_detectors_schema'; import { jobServiceProvider } from '../models/job_service'; import { categorizationExamplesProvider } from '../models/job_service/new_job'; import { getAuthorizationHeader } from '../lib/request_authorization'; -import { Datafeed, Job } from '../../common/types/anomaly_detection_jobs'; +import type { Datafeed, Job } from '../../common/types/anomaly_detection_jobs'; /** * Routes for job service @@ -535,21 +535,24 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { - try { - const { indexPattern } = request.params; - const isRollup = request.query?.rollup === 'true'; - const savedObjectsClient = context.core.savedObjects.client; - const { newJobCaps } = jobServiceProvider(client, mlClient); - const resp = await newJobCaps(indexPattern, isRollup, savedObjectsClient); - - return response.ok({ - body: resp, - }); - } catch (e) { - return response.customError(wrapError(e)); + routeGuard.fullLicenseAPIGuard( + async ({ client, mlClient, request, response, getDataViewsService }) => { + try { + const { indexPattern } = request.params; + const isRollup = request.query?.rollup === 'true'; + const { newJobCaps } = jobServiceProvider(client, mlClient); + + const dataViewsService = await getDataViewsService(); + const resp = await newJobCaps(indexPattern, isRollup, dataViewsService); + + return response.ok({ + body: resp, + }); + } catch (e) { + return response.customError(wrapError(e)); + } } - }) + ) ); /** diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index 097f3f8d67652..d814e91f70ca0 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -5,19 +5,24 @@ * 2.0. */ -import { TypeOf } from '@kbn/config-schema'; +import type { TypeOf } from '@kbn/config-schema'; -import { IScopedClusterClient, KibanaRequest, SavedObjectsClientContract } from 'kibana/server'; -import { DatafeedOverride, JobOverride } from '../../common/types/modules'; +import type { + IScopedClusterClient, + KibanaRequest, + SavedObjectsClientContract, +} from 'kibana/server'; +import type { DataViewsService } from '../../../../../src/plugins/data_views/common'; +import type { DatafeedOverride, JobOverride } from '../../common/types/modules'; import { wrapError } from '../client/error_wrapper'; -import { DataRecognizer } from '../models/data_recognizer'; +import { dataRecognizerFactory } from '../models/data_recognizer'; import { moduleIdParamSchema, optionalModuleIdParamSchema, modulesIndexPatternTitleSchema, setupModuleBodySchema, } from './schemas/modules'; -import { RouteInitialization } from '../types'; +import type { RouteInitialization } from '../types'; import type { MlClient } from '../lib/ml_client'; import type { JobSavedObjectService } from '../saved_objects'; @@ -25,14 +30,16 @@ function recognize( client: IScopedClusterClient, mlClient: MlClient, savedObjectsClient: SavedObjectsClientContract, + dataViewsService: DataViewsService, jobSavedObjectService: JobSavedObjectService, request: KibanaRequest, indexPatternTitle: string ) { - const dr = new DataRecognizer( + const dr = dataRecognizerFactory( client, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -43,14 +50,16 @@ function getModule( client: IScopedClusterClient, mlClient: MlClient, savedObjectsClient: SavedObjectsClientContract, + dataViewsService: DataViewsService, jobSavedObjectService: JobSavedObjectService, request: KibanaRequest, moduleId?: string ) { - const dr = new DataRecognizer( + const dr = dataRecognizerFactory( client, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -65,6 +74,7 @@ function setup( client: IScopedClusterClient, mlClient: MlClient, savedObjectsClient: SavedObjectsClientContract, + dataViewsService: DataViewsService, jobSavedObjectService: JobSavedObjectService, request: KibanaRequest, moduleId: string, @@ -81,10 +91,11 @@ function setup( estimateModelMemory?: boolean, applyToAllSpaces?: boolean ) { - const dr = new DataRecognizer( + const dr = dataRecognizerFactory( client, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -109,14 +120,16 @@ function dataRecognizerJobsExist( client: IScopedClusterClient, mlClient: MlClient, savedObjectsClient: SavedObjectsClientContract, + dataViewsService: DataViewsService, jobSavedObjectService: JobSavedObjectService, request: KibanaRequest, moduleId: string ) { - const dr = new DataRecognizer( + const dr = dataRecognizerFactory( client, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -166,13 +179,23 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }, }, routeGuard.fullLicenseAPIGuard( - async ({ client, mlClient, request, response, context, jobSavedObjectService }) => { + async ({ + client, + mlClient, + request, + response, + context, + jobSavedObjectService, + getDataViewsService, + }) => { try { const { indexPatternTitle } = request.params; + const dataViewService = await getDataViewsService(); const results = await recognize( client, mlClient, context.core.savedObjects.client, + dataViewService, jobSavedObjectService, request, indexPatternTitle @@ -305,7 +328,15 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }, }, routeGuard.fullLicenseAPIGuard( - async ({ client, mlClient, request, response, context, jobSavedObjectService }) => { + async ({ + client, + mlClient, + request, + response, + context, + jobSavedObjectService, + getDataViewsService, + }) => { try { let { moduleId } = request.params; if (moduleId === '') { @@ -313,10 +344,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { // the moduleId will be an empty string. moduleId = undefined; } + const dataViewService = await getDataViewsService(); const results = await getModule( client, mlClient, context.core.savedObjects.client, + dataViewService, jobSavedObjectService, request, moduleId @@ -482,7 +515,15 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }, }, routeGuard.fullLicenseAPIGuard( - async ({ client, mlClient, request, response, context, jobSavedObjectService }) => { + async ({ + client, + mlClient, + request, + response, + context, + jobSavedObjectService, + getDataViewsService, + }) => { try { const { moduleId } = request.params; @@ -501,10 +542,13 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { applyToAllSpaces, } = request.body as TypeOf<typeof setupModuleBodySchema>; + const dataViewService = await getDataViewsService(); + const result = await setup( client, mlClient, context.core.savedObjects.client, + dataViewService, jobSavedObjectService, request, moduleId, @@ -593,13 +637,23 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }, }, routeGuard.fullLicenseAPIGuard( - async ({ client, mlClient, request, response, context, jobSavedObjectService }) => { + async ({ + client, + mlClient, + request, + response, + context, + jobSavedObjectService, + getDataViewsService, + }) => { try { const { moduleId } = request.params; + const dataViewService = await getDataViewsService(); const result = await dataRecognizerJobsExist( client, mlClient, context.core.savedObjects.client, + dataViewService, jobSavedObjectService, request, moduleId diff --git a/x-pack/plugins/ml/server/shared_services/providers/modules.ts b/x-pack/plugins/ml/server/shared_services/providers/modules.ts index c86a40e4224ce..f6a6c58fadb4e 100644 --- a/x-pack/plugins/ml/server/shared_services/providers/modules.ts +++ b/x-pack/plugins/ml/server/shared_services/providers/modules.ts @@ -5,13 +5,12 @@ * 2.0. */ -import { IScopedClusterClient, KibanaRequest, SavedObjectsClientContract } from 'kibana/server'; -import { TypeOf } from '@kbn/config-schema'; -import { DataRecognizer } from '../../models/data_recognizer'; -import { GetGuards } from '../shared_services'; +import type { KibanaRequest, SavedObjectsClientContract } from 'kibana/server'; +import type { TypeOf } from '@kbn/config-schema'; +import type { PluginStart as DataViewsPluginStart } from '../../../../../../src/plugins/data_views/server'; +import type { GetGuards } from '../shared_services'; +import { DataRecognizer, dataRecognizerFactory } from '../../models/data_recognizer'; import { moduleIdParamSchema, setupModuleBodySchema } from '../../routes/schemas/modules'; -import { MlClient } from '../../lib/ml_client'; -import { JobSavedObjectService } from '../../saved_objects'; export type ModuleSetupPayload = TypeOf<typeof moduleIdParamSchema> & TypeOf<typeof setupModuleBodySchema>; @@ -28,7 +27,10 @@ export interface ModulesProvider { }; } -export function getModulesProvider(getGuards: GetGuards): ModulesProvider { +export function getModulesProvider( + getGuards: GetGuards, + getDataViews: () => DataViewsPluginStart +): ModulesProvider { return { modulesProvider(request: KibanaRequest, savedObjectsClient: SavedObjectsClientContract) { return { @@ -36,11 +38,13 @@ export function getModulesProvider(getGuards: GetGuards): ModulesProvider { return await getGuards(request, savedObjectsClient) .isFullLicense() .hasMlCapabilities(['canGetJobs']) - .ok(async ({ scopedClient, mlClient, jobSavedObjectService }) => { + .ok(async ({ scopedClient, mlClient, jobSavedObjectService, getDataViewsService }) => { + const dataViewsService = await getDataViewsService(); const dr = dataRecognizerFactory( scopedClient, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -51,11 +55,13 @@ export function getModulesProvider(getGuards: GetGuards): ModulesProvider { return await getGuards(request, savedObjectsClient) .isFullLicense() .hasMlCapabilities(['canGetJobs']) - .ok(async ({ scopedClient, mlClient, jobSavedObjectService }) => { + .ok(async ({ scopedClient, mlClient, jobSavedObjectService, getDataViewsService }) => { + const dataViewsService = await getDataViewsService(); const dr = dataRecognizerFactory( scopedClient, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -66,11 +72,13 @@ export function getModulesProvider(getGuards: GetGuards): ModulesProvider { return await getGuards(request, savedObjectsClient) .isFullLicense() .hasMlCapabilities(['canGetJobs']) - .ok(async ({ scopedClient, mlClient, jobSavedObjectService }) => { + .ok(async ({ scopedClient, mlClient, jobSavedObjectService, getDataViewsService }) => { + const dataViewsService = await getDataViewsService(); const dr = dataRecognizerFactory( scopedClient, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -81,11 +89,13 @@ export function getModulesProvider(getGuards: GetGuards): ModulesProvider { return await getGuards(request, savedObjectsClient) .isFullLicense() .hasMlCapabilities(['canCreateJob']) - .ok(async ({ scopedClient, mlClient, jobSavedObjectService }) => { + .ok(async ({ scopedClient, mlClient, jobSavedObjectService, getDataViewsService }) => { + const dataViewsService = await getDataViewsService(); const dr = dataRecognizerFactory( scopedClient, mlClient, savedObjectsClient, + dataViewsService, jobSavedObjectService, request ); @@ -109,13 +119,3 @@ export function getModulesProvider(getGuards: GetGuards): ModulesProvider { }, }; } - -function dataRecognizerFactory( - client: IScopedClusterClient, - mlClient: MlClient, - savedObjectsClient: SavedObjectsClientContract, - jobSavedObjectService: JobSavedObjectService, - request: KibanaRequest -) { - return new DataRecognizer(client, mlClient, savedObjectsClient, jobSavedObjectService, request); -} diff --git a/x-pack/plugins/ml/server/shared_services/shared_services.ts b/x-pack/plugins/ml/server/shared_services/shared_services.ts index 5c8bbffe10aed..9c8ab1e069258 100644 --- a/x-pack/plugins/ml/server/shared_services/shared_services.ts +++ b/x-pack/plugins/ml/server/shared_services/shared_services.ts @@ -5,17 +5,18 @@ * 2.0. */ -import { +import type { IClusterClient, IScopedClusterClient, SavedObjectsClientContract, UiSettingsServiceStart, } from 'kibana/server'; -import { SpacesPluginStart } from '../../../spaces/server'; +import type { SpacesPluginStart } from '../../../spaces/server'; import { KibanaRequest } from '../../.././../../src/core/server'; import { MlLicense } from '../../common/license'; import type { CloudSetup } from '../../../cloud/server'; +import type { PluginStart as DataViewsPluginStart } from '../../../../../src/plugins/data_views/server'; import type { SecurityPluginSetup } from '../../../security/server'; import { licenseChecks } from './license_checks'; import { MlSystemProvider, getMlSystemProvider } from './providers/system'; @@ -26,7 +27,7 @@ import { AnomalyDetectorsProvider, getAnomalyDetectorsProvider, } from './providers/anomaly_detectors'; -import { ResolveMlCapabilities, MlCapabilitiesKey } from '../../common/types/capabilities'; +import type { ResolveMlCapabilities, MlCapabilitiesKey } from '../../common/types/capabilities'; import { hasMlCapabilitiesProvider, HasMlCapabilities } from '../lib/capabilities'; import { MLClusterClientUninitialized, @@ -45,6 +46,7 @@ import { } from '../lib/alerts/jobs_health_service'; import type { FieldFormatsStart } from '../../../../../src/plugins/field_formats/server'; import type { FieldFormatsRegistryProvider } from '../../common/types/kibana'; +import { getDataViewsServiceFactory, GetDataViewsService } from '../lib/data_views_utils'; export type SharedServices = JobServiceProvider & AnomalyDetectorsProvider & @@ -76,6 +78,7 @@ interface OkParams { mlClient: MlClient; jobSavedObjectService: JobSavedObjectService; getFieldsFormatRegistry: FieldFormatsRegistryProvider; + getDataViewsService: GetDataViewsService; } type OkCallback = (okParams: OkParams) => any; @@ -90,6 +93,7 @@ export function createSharedServices( getInternalSavedObjectsClient: () => SavedObjectsClientContract | null, getUiSettings: () => UiSettingsServiceStart | null, getFieldsFormat: () => FieldFormatsStart | null, + getDataViews: () => DataViewsPluginStart, isMlReady: () => Promise<void> ): { sharedServicesProviders: SharedServices; @@ -101,6 +105,7 @@ export function createSharedServices( savedObjectsClient: SavedObjectsClientContract ): Guards { const internalSavedObjectsClient = getInternalSavedObjectsClient(); + if (internalSavedObjectsClient === null) { throw new Error('Internal saved object client not initialized'); } @@ -113,7 +118,8 @@ export function createSharedServices( getSpaces !== undefined, isMlReady, getUiSettings, - getFieldsFormat + getFieldsFormat, + getDataViews ); const { @@ -122,6 +128,7 @@ export function createSharedServices( mlClient, jobSavedObjectService, getFieldsFormatRegistry, + getDataViewsService, } = getRequestItems(request); const asyncGuards: Array<Promise<void>> = []; @@ -140,7 +147,13 @@ export function createSharedServices( }, async ok(callback: OkCallback) { await Promise.all(asyncGuards); - return callback({ scopedClient, mlClient, jobSavedObjectService, getFieldsFormatRegistry }); + return callback({ + scopedClient, + mlClient, + jobSavedObjectService, + getFieldsFormatRegistry, + getDataViewsService, + }); }, }; return guards; @@ -153,7 +166,7 @@ export function createSharedServices( sharedServicesProviders: { ...getJobServiceProvider(getGuards), ...getAnomalyDetectorsProvider(getGuards), - ...getModulesProvider(getGuards), + ...getModulesProvider(getGuards, getDataViews), ...getResultsServiceProvider(getGuards), ...getMlSystemProvider(getGuards, mlLicense, getSpaces, cloud, resolveMlCapabilities), ...getAlertingServiceProvider(getGuards), @@ -176,7 +189,8 @@ function getRequestItemsProvider( spaceEnabled: boolean, isMlReady: () => Promise<void>, getUiSettings: () => UiSettingsServiceStart | null, - getFieldsFormat: () => FieldFormatsStart | null + getFieldsFormat: () => FieldFormatsStart | null, + getDataViews: () => DataViewsPluginStart ) { return (request: KibanaRequest) => { const getHasMlCapabilities = hasMlCapabilitiesProvider(resolveMlCapabilities); @@ -234,12 +248,20 @@ function getRequestItemsProvider( }; mlClient = getMlClient(scopedClient, jobSavedObjectService); } + + const getDataViewsService = getDataViewsServiceFactory( + getDataViews, + savedObjectsClient, + scopedClient + ); + return { hasMlCapabilities, scopedClient, mlClient, jobSavedObjectService, getFieldsFormatRegistry, + getDataViewsService, }; }; } diff --git a/x-pack/plugins/ml/server/types.ts b/x-pack/plugins/ml/server/types.ts index da83b03766af4..d5c67bf99a7a0 100644 --- a/x-pack/plugins/ml/server/types.ts +++ b/x-pack/plugins/ml/server/types.ts @@ -23,6 +23,7 @@ import type { PluginSetup as DataPluginSetup, PluginStart as DataPluginStart, } from '../../../../src/plugins/data/server'; +import type { PluginStart as DataViewsPluginStart } from '../../../../src/plugins/data_views/server'; import type { FieldFormatsSetup, FieldFormatsStart, @@ -64,6 +65,7 @@ export interface PluginsSetup { export interface PluginsStart { data: DataPluginStart; + dataViews: DataViewsPluginStart; fieldFormats: FieldFormatsStart; spaces?: SpacesPluginStart; } diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index db8fc463b0550..0c108f8b3b8a5 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -21,6 +21,7 @@ { "path": "../../../src/core/tsconfig.json" }, { "path": "../../../src/plugins/embeddable/tsconfig.json" }, { "path": "../../../src/plugins/index_pattern_management/tsconfig.json" }, + { "path": "../../../src/plugins/data_views/tsconfig.json" }, { "path": "../cloud/tsconfig.json" }, { "path": "../features/tsconfig.json" }, { "path": "../data_visualizer/tsconfig.json"}, diff --git a/x-pack/plugins/monitoring/common/types/alerts.ts b/x-pack/plugins/monitoring/common/types/alerts.ts index bbd217169469d..9abca4cbdc948 100644 --- a/x-pack/plugins/monitoring/common/types/alerts.ts +++ b/x-pack/plugins/monitoring/common/types/alerts.ts @@ -208,9 +208,11 @@ export interface CCRReadExceptionsUIMeta extends CCRReadExceptionsStats { itemLabel: string; } -export interface IndexShardSizeStats extends AlertNodeStats { +export interface IndexShardSizeStats { shardIndex: string; shardSize: number; + clusterUuid: string; + ccs?: string; } export interface IndexShardSizeUIMeta extends IndexShardSizeStats { diff --git a/x-pack/plugins/monitoring/public/application/index.tsx b/x-pack/plugins/monitoring/public/application/index.tsx index 7b4c73475338f..2caead4f963a1 100644 --- a/x-pack/plugins/monitoring/public/application/index.tsx +++ b/x-pack/plugins/monitoring/public/application/index.tsx @@ -59,9 +59,15 @@ import { LogStashNodePipelinesPage } from './pages/logstash/node_pipelines'; export const renderApp = ( core: CoreStart, plugins: MonitoringStartPluginDependencies, - { element, setHeaderActionMenu }: AppMountParameters, + { element, history, setHeaderActionMenu }: AppMountParameters, externalConfig: ExternalConfig ) => { + // dispatch synthetic hash change event to update hash history objects + // this is necessary because hash updates triggered by using popState won't trigger this event naturally. + const unlistenParentHistory = history.listen(() => { + window.dispatchEvent(new HashChangeEvent('hashchange')); + }); + ReactDOM.render( <MonitoringApp core={core} @@ -74,6 +80,7 @@ export const renderApp = ( return () => { ReactDOM.unmountComponentAtNode(element); + unlistenParentHistory(); }; }; diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx index 3bab01af8ceb7..7a070c735bbea 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx @@ -23,6 +23,7 @@ export const BeatsTemplate: React.FC<BeatsTemplateProps> = ({ instance, ...props defaultMessage: 'Overview', }), route: '/beats', + testSubj: 'beatsOverviewPage', }); tabs.push({ id: 'instances', @@ -30,6 +31,7 @@ export const BeatsTemplate: React.FC<BeatsTemplateProps> = ({ instance, ...props defaultMessage: 'Instances', }), route: '/beats/beats', + testSubj: 'beatsListingPage', }); } else { tabs.push({ diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx index 489ad110c40fd..4611f17159621 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx @@ -71,12 +71,7 @@ export const BeatsInstancesPage: React.FC<ComponentProps> = ({ clusters }) => { ]); return ( - <BeatsTemplate - title={title} - pageTitle={pageTitle} - getPageData={getPageData} - data-test-subj="beatsListingPage" - > + <BeatsTemplate title={title} pageTitle={pageTitle} getPageData={getPageData}> <div data-test-subj="monitoringBeatsInstancesApp"> <SetupModeRenderer productName={BEATS_SYSTEM_ID} diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx index 1fa37a2c7b3e6..aec89c92055c4 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx @@ -72,13 +72,8 @@ export const BeatsOverviewPage: React.FC<ComponentProps> = ({ clusters }) => { }; return ( - <BeatsTemplate - title={title} - pageTitle={pageTitle} - getPageData={getPageData} - data-test-subj="beatsOverviewPage" - > - <div data-test-subj="beatsOverviewPage">{renderOverview(data)}</div> + <BeatsTemplate title={title} pageTitle={pageTitle} getPageData={getPageData}> + <div>{renderOverview(data)}</div> </BeatsTemplate> ); }; diff --git a/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx b/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx index b78df27cd12c4..04074762c8d22 100644 --- a/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx @@ -50,7 +50,7 @@ export const ClusterOverview: React.FC<{}> = () => { { id: 'clusterName', label: clusters[0].cluster_name, - testSubj: 'clusterName', + testSubj: 'overviewTabsclusterName', route: '/overview', }, ]; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx index 13e21912df896..aa7ca97219206 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx @@ -12,7 +12,7 @@ import { TabMenuItem, PageTemplateProps } from '../page_template'; import { ML_SUPPORTED_LICENSES } from '../../../../common/constants'; interface ElasticsearchTemplateProps extends PageTemplateProps { - cluster: any; + cluster?: any; } export const ElasticsearchTemplate: React.FC<ElasticsearchTemplateProps> = ({ @@ -43,7 +43,7 @@ export const ElasticsearchTemplate: React.FC<ElasticsearchTemplateProps> = ({ }, ]; - if (mlIsSupported(cluster.license)) { + if (cluster && mlIsSupported(cluster.license)) { tabs.push({ id: 'ml', label: i18n.translate('xpack.monitoring.esNavigation.jobsLinkText', { @@ -53,7 +53,7 @@ export const ElasticsearchTemplate: React.FC<ElasticsearchTemplateProps> = ({ }); } - if (cluster.isCcrEnabled) { + if (cluster?.isCcrEnabled) { tabs.push({ id: 'ccr', label: i18n.translate('xpack.monitoring.esNavigation.ccrLinkText', { diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx index ed36306cbbd64..ac7e267cbc9ac 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx @@ -33,6 +33,7 @@ export const ElasticsearchNodesPage: React.FC<ComponentProps> = ({ clusters }) = const globalState = useContext(GlobalStateContext); const { showCgroupMetricsElasticsearch } = useContext(ExternalConfigContext); const { services } = useKibana<{ data: any }>(); + const [isLoading, setIsLoading] = React.useState(false); const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); const { getPaginationRouteOptions, updateTotalItemCount, getPaginationTableProps } = useTable('elasticsearch.nodes'); @@ -64,6 +65,7 @@ export const ElasticsearchNodesPage: React.FC<ComponentProps> = ({ clusters }) = const bounds = services.data?.query.timefilter.timefilter.getBounds(); const url = `../api/monitoring/v1/clusters/${clusterUuid}/elasticsearch/nodes`; if (services.http?.fetch && clusterUuid) { + setIsLoading(true); const response = await services.http?.fetch(url, { method: 'POST', body: JSON.stringify({ @@ -76,6 +78,7 @@ export const ElasticsearchNodesPage: React.FC<ComponentProps> = ({ clusters }) = }), }); + setIsLoading(false); setData(response); updateTotalItemCount(response.totalNodeCount); const alertsResponse = await fetchAlerts({ @@ -125,6 +128,7 @@ export const ElasticsearchNodesPage: React.FC<ComponentProps> = ({ clusters }) = setupMode={setupMode} nodes={data.nodes} alerts={alerts} + isLoading={isLoading} showCgroupMetricsElasticsearch={showCgroupMetricsElasticsearch} {...getPaginationTableProps()} /> diff --git a/x-pack/plugins/monitoring/public/application/pages/loading_page.tsx b/x-pack/plugins/monitoring/public/application/pages/loading_page.tsx index d5c1bcf80c23e..ebc43dd5c627e 100644 --- a/x-pack/plugins/monitoring/public/application/pages/loading_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/loading_page.tsx @@ -15,12 +15,20 @@ import { CODE_PATH_ELASTICSEARCH } from '../../../common/constants'; const CODE_PATHS = [CODE_PATH_ELASTICSEARCH]; -export const LoadingPage = () => { +export const LoadingPage = ({ staticLoadingState }: { staticLoadingState?: boolean }) => { const { clusters, loaded } = useClusters(null, undefined, CODE_PATHS); const title = i18n.translate('xpack.monitoring.loading.pageTitle', { defaultMessage: 'Loading', }); + if (staticLoadingState) { + return ( + <PageTemplate title={title}> + <PageLoading />; + </PageTemplate> + ); + } + return ( <PageTemplate title={title}> {loaded === false ? <PageLoading /> : renderRedirections(clusters)} diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx index e09850eaad5c9..740202da57d24 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx @@ -58,7 +58,6 @@ export const LogStashNodePipelinesPage: React.FC<ComponentProps> = ({ clusters } const getPageData = useCallback(async () => { const bounds = services.data?.query.timefilter.timefilter.getBounds(); - const options: any = getPaginationRouteOptions(); const url = `../api/monitoring/v1/clusters/${clusterUuid}/logstash/node/${match.params.uuid}/pipelines`; const response = await services.http?.fetch(url, { method: 'POST', @@ -68,8 +67,7 @@ export const LogStashNodePipelinesPage: React.FC<ComponentProps> = ({ clusters } min: bounds.min.toISOString(), max: bounds.max.toISOString(), }, - pagination: options.pagination, - queryText: options.queryText, + ...getPaginationRouteOptions(), }), }); diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx index ac750ff81ddaa..c2dfe1c0dae7d 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx @@ -46,7 +46,6 @@ export const LogStashPipelinesPage: React.FC<ComponentProps> = ({ clusters }) => const bounds = services.data?.query.timefilter.timefilter.getBounds(); const url = `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipelines`; - const options: any = getPaginationRouteOptions(); const response = await services.http?.fetch(url, { method: 'POST', body: JSON.stringify({ @@ -55,8 +54,7 @@ export const LogStashPipelinesPage: React.FC<ComponentProps> = ({ clusters }) => min: bounds.min.toISOString(), max: bounds.max.toISOString(), }, - pagination: options.pagination, - queryText: options.queryText, + ...getPaginationRouteOptions(), }), }); @@ -96,10 +94,10 @@ export const LogStashPipelinesPage: React.FC<ComponentProps> = ({ clusters }) => title={title} pageTitle={pageTitle} getPageData={getPageData} - data-test-subj="elasticsearchOverviewPage" + data-test-subj="logstashPipelinesListing" cluster={cluster} > - <div data-test-subj="elasticsearchOverviewPage">{renderOverview(data)}</div> + <div data-test-subj="logstashPipelinesListing">{renderOverview(data)}</div> </LogstashTemplate> ); }; diff --git a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx index 5c030814d9cdf..23eeb2c034a80 100644 --- a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx @@ -92,7 +92,7 @@ export const PageTemplate: React.FC<PageTemplateProps> = ({ }; return ( - <div className="app-container"> + <div className="app-container" data-test-subj="monitoringAppContainer"> <ActionMenu> <AlertsDropdown /> </ActionMenu> diff --git a/x-pack/plugins/monitoring/public/application/route_init.tsx b/x-pack/plugins/monitoring/public/application/route_init.tsx index 8a11df3de50ae..52780aa280707 100644 --- a/x-pack/plugins/monitoring/public/application/route_init.tsx +++ b/x-pack/plugins/monitoring/public/application/route_init.tsx @@ -9,6 +9,8 @@ import { Route, Redirect, useLocation } from 'react-router-dom'; import { useClusters } from './hooks/use_clusters'; import { GlobalStateContext } from './contexts/global_state_context'; import { getClusterFromClusters } from '../lib/get_cluster_from_clusters'; +import { isInSetupMode } from './setup_mode'; +import { LoadingPage } from './pages/loading_page'; export interface ComponentProps { clusters: []; @@ -34,13 +36,12 @@ export const RouteInit: React.FC<RouteInitProps> = ({ const { clusters, loaded } = useClusters(clusterUuid, undefined, codePaths); - // TODO: we will need this when setup mode is migrated - // const inSetupMode = isInSetupMode(); + const inSetupMode = isInSetupMode(undefined, globalState); const cluster = getClusterFromClusters(clusters, globalState, unsetGlobalState); // TODO: check for setupMode too when the setup mode is migrated - if (loaded && !cluster) { + if (loaded && !cluster && !inSetupMode) { return <Redirect to="/no-data" />; } @@ -56,7 +57,7 @@ export const RouteInit: React.FC<RouteInitProps> = ({ // check if we need to redirect because of attempt at unsupported multi-cluster monitoring const clusterSupported = cluster.isSupported || clusters.length === 1; - if (location.pathname !== 'home' && !clusterSupported) { + if (location.pathname !== '/home' && !clusterSupported) { return <Redirect to="/home" />; } } @@ -66,7 +67,9 @@ export const RouteInit: React.FC<RouteInitProps> = ({ <Route path={path}> <Component clusters={clusters} /> </Route> - ) : null; + ) : ( + <LoadingPage staticLoadingState /> + ); }; const isExpired = (license: any): boolean => { diff --git a/x-pack/plugins/monitoring/public/application/setup_mode/index.ts b/x-pack/plugins/monitoring/public/application/setup_mode/index.ts new file mode 100644 index 0000000000000..1bcdcdef09c28 --- /dev/null +++ b/x-pack/plugins/monitoring/public/application/setup_mode/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 './setup_mode'; diff --git a/x-pack/plugins/monitoring/public/application/setup_mode/setup_mode.tsx b/x-pack/plugins/monitoring/public/application/setup_mode/setup_mode.tsx index bfdf96ef5b2c1..828d5a2d20ae6 100644 --- a/x-pack/plugins/monitoring/public/application/setup_mode/setup_mode.tsx +++ b/x-pack/plugins/monitoring/public/application/setup_mode/setup_mode.tsx @@ -177,7 +177,7 @@ export const initSetupModeState = async ( } }; -export const isInSetupMode = (context?: ISetupModeContext) => { +export const isInSetupMode = (context?: ISetupModeContext, gState: GlobalState = globalState) => { if (context?.setupModeSupported === false) { return false; } @@ -185,7 +185,7 @@ export const isInSetupMode = (context?: ISetupModeContext) => { return true; } - return globalState.inSetupMode; + return gState.inSetupMode; }; export const isSetupModeFeatureEnabled = (feature: SetupModeFeature) => { diff --git a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_active.test.js.snap b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_active.test.js.snap index b7d57b9bb5d9d..c4ce91823ce03 100644 --- a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_active.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_active.test.js.snap @@ -39,7 +39,12 @@ exports[`Latest Active that latest active component renders normally 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_types.test.js.snap b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_types.test.js.snap index 0021bfae57d6e..4b4f5ca654971 100644 --- a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_types.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_types.test.js.snap @@ -31,7 +31,12 @@ exports[`Latest Types that latest active component renders normally 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_versions.test.js.snap b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_versions.test.js.snap index 93ff1299323a0..88e673eb8dcea 100644 --- a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_versions.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/latest_versions.test.js.snap @@ -27,7 +27,12 @@ exports[`Latest Versions that latest active component renders normally 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/x-pack/plugins/monitoring/public/components/logs/__snapshots__/logs.test.js.snap b/x-pack/plugins/monitoring/public/components/logs/__snapshots__/logs.test.js.snap index 28389ef3c3211..3e439f263a613 100644 --- a/x-pack/plugins/monitoring/public/components/logs/__snapshots__/logs.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/logs/__snapshots__/logs.test.js.snap @@ -268,7 +268,12 @@ exports[`Logs should render normally 1`] = ` }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js b/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js index cbf589d5de2a0..0c12e91512bd4 100644 --- a/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js +++ b/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js @@ -23,6 +23,7 @@ export function EuiMonitoringSSPTable({ ...props }) { const [queryText, setQueryText] = React.useState(''); + const [isLoading, setIsLoading] = React.useState(false); const [page, setPage] = React.useState({ index: pagination.pageIndex, size: pagination.pageSize, @@ -72,7 +73,9 @@ export function EuiMonitoringSSPTable({ setSort({ sort }); // angular version if (props.fetchMoreData) { + setIsLoading(true); await props.fetchMoreData({ page, sort: { sort }, queryText }); + setIsLoading(false); onTableChange({ page, sort }); } // react version @@ -87,7 +90,9 @@ export function EuiMonitoringSSPTable({ setQueryText(queryText); // angular version if (props.fetchMoreData) { + setIsLoading(true); await props.fetchMoreData({ page: newPage, sort, queryText }); + setIsLoading(false); } else { // react version onTableChange({ page, sort: sort.sort, queryText }); @@ -105,6 +110,7 @@ export function EuiMonitoringSSPTable({ pagination={pagination} onChange={onChange} columns={columns} + loading={props.isLoading || isLoading} /> {footerContent} </div> diff --git a/x-pack/plugins/monitoring/public/directives/main/index.html b/x-pack/plugins/monitoring/public/directives/main/index.html index 558ed5e874cd6..fd14120e1db2f 100644 --- a/x-pack/plugins/monitoring/public/directives/main/index.html +++ b/x-pack/plugins/monitoring/public/directives/main/index.html @@ -1,4 +1,4 @@ -<div class="app-container"> +<div class="app-container" data-test-subj="monitoringAppContainer"> <div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive"> <div class="euiFlexItem euiFlexItem--flexGrowZero"> <div class="euiFlexGroup euiFlexGroup--gutterNone euiFlexGroup--justifyContentSpaceEvenly euiFlexGroup--responsive euiFlexGroup--directionColumn"> @@ -299,7 +299,7 @@ <h1 class="euiTitle euiTitle--xsmall">{{pageTitle || monitoringMain.instance}}</ </div> <div ng-if="monitoringMain.inOverview" class="euiTabs" role="navigation"> - <a class="euiTab" data-test-subj="clusterName">{{ pageData.cluster_name }}</a> + <a class="euiTab" data-test-subj="overviewTabsclusterName">{{ pageData.cluster_name }}</a> </div> <div ng-if="monitoringMain.inAlerts" class="euiTabs" role="navigation"> diff --git a/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.test.ts b/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.test.ts index 0b8509c4fa56a..f7d6081edd306 100644 --- a/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.test.ts +++ b/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.test.ts @@ -85,14 +85,10 @@ describe('LargeShardSizeRule', () => { const shardSize = 0; const clusterUuid = 'abc123'; const clusterName = 'testCluster'; - const nodeId = 'myNodeId'; - const nodeName = 'myNodeName'; const stat = { shardIndex, shardSize, clusterUuid, - nodeId, - nodeName, }; const replaceState = jest.fn(); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts index 98bb546b43ab9..9259adc63e546 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts @@ -11,12 +11,8 @@ import { ElasticsearchIndexStats, ElasticsearchResponseHit } from '../../../comm import { ESGlobPatterns, RegExPatterns } from '../../../common/es_glob_patterns'; import { Globals } from '../../static_globals'; -interface SourceNode { - name: string; - uuid: string; -} type TopHitType = ElasticsearchResponseHit & { - _source: { index_stats?: Partial<ElasticsearchIndexStats>; source_node?: SourceNode }; + _source: { index_stats?: Partial<ElasticsearchIndexStats> }; }; const memoizedIndexPatterns = (globPatterns: string) => { @@ -90,8 +86,6 @@ export async function fetchIndexShardSize( '_index', 'index_stats.shards.primaries', 'index_stats.primaries.store.size_in_bytes', - 'source_node.name', - 'source_node.uuid', ], }, size: 1, @@ -135,10 +129,10 @@ export async function fetchIndexShardSize( } const { _index: monitoringIndexName, - _source: { source_node: sourceNode, index_stats: indexStats }, + _source: { index_stats: indexStats }, } = topHit; - if (!indexStats || !indexStats.primaries || !sourceNode) { + if (!indexStats || !indexStats.primaries) { continue; } @@ -151,7 +145,6 @@ export async function fetchIndexShardSize( * We can only calculate the average primary shard size at this point, since we don't have * data (in .monitoring-es* indices) to give us individual shards. This might change in the future */ - const { name: nodeName, uuid: nodeId } = sourceNode; const avgShardSize = primaryShardSizeBytes / totalPrimaryShards; if (avgShardSize < thresholdBytes) { continue; @@ -161,8 +154,6 @@ export async function fetchIndexShardSize( shardIndex, shardSize, clusterUuid, - nodeName, - nodeId, ccs: monitoringIndexName.includes(':') ? monitoringIndexName.split(':')[0] : undefined, }); } diff --git a/x-pack/plugins/observability/common/typings.ts b/x-pack/plugins/observability/common/typings.ts index 71337075e1617..bccb0f4491009 100644 --- a/x-pack/plugins/observability/common/typings.ts +++ b/x-pack/plugins/observability/common/typings.ts @@ -16,14 +16,12 @@ export const alertWorkflowStatusRt = t.keyof({ export type AlertWorkflowStatus = t.TypeOf<typeof alertWorkflowStatusRt>; export interface ApmIndicesConfig { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': string; - 'apm_oss.errorIndices': string; - 'apm_oss.onboardingIndices': string; - 'apm_oss.spanIndices': string; - 'apm_oss.transactionIndices': string; - 'apm_oss.metricsIndices': string; - /* eslint-enable @typescript-eslint/naming-convention */ + sourcemap: string; + error: string; + onboarding: string; + span: string; + transaction: string; + metric: string; apmAgentConfigurationIndex: string; apmCustomLinkIndex: string; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 68dcd77e98990..e4473b183d729 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { OperationType } from '../../../../../../../lens/public'; import { ReportViewType } from '../../types'; import { CLS_FIELD, @@ -13,6 +13,7 @@ import { LCP_FIELD, TBT_FIELD, TRANSACTION_TIME_TO_FIRST_BYTE, + TRANSACTION_DURATION, } from './elasticsearch_fieldnames'; import { AGENT_HOST_LABEL, @@ -45,6 +46,8 @@ import { TBT_LABEL, URL_LABEL, BACKEND_TIME_LABEL, + MONITORS_DURATION_LABEL, + PAGE_LOAD_TIME_LABEL, LABELS_FIELD, } from './labels'; @@ -69,9 +72,11 @@ export const FieldLabels: Record<string, string> = { [FID_FIELD]: FID_LABEL, [CLS_FIELD]: CLS_LABEL, [TRANSACTION_TIME_TO_FIRST_BYTE]: BACKEND_TIME_LABEL, + [TRANSACTION_DURATION]: PAGE_LOAD_TIME_LABEL, 'monitor.id': MONITOR_ID_LABEL, 'monitor.status': MONITOR_STATUS_LABEL, + 'monitor.duration.us': MONITORS_DURATION_LABEL, 'agent.hostname': AGENT_HOST_LABEL, 'host.hostname': HOST_NAME_LABEL, @@ -86,6 +91,7 @@ export const FieldLabels: Record<string, string> = { 'performance.metric': METRIC_LABEL, 'Business.KPI': KPI_LABEL, 'http.request.method': REQUEST_METHOD, + percentile: 'Percentile', LABEL_FIELDS_FILTER: LABELS_FIELD, LABEL_FIELDS_BREAKDOWN: 'Labels field', }; @@ -114,8 +120,16 @@ export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN'; export const FILTER_RECORDS = 'FILTER_RECORDS'; export const TERMS_COLUMN = 'TERMS_COLUMN'; export const OPERATION_COLUMN = 'operation'; +export const PERCENTILE = 'percentile'; export const REPORT_METRIC_FIELD = 'REPORT_METRIC_FIELD'; +export const PERCENTILE_RANKS = [ + '99th' as OperationType, + '95th' as OperationType, + '90th' as OperationType, + '75th' as OperationType, + '50th' as OperationType, +]; export const LABEL_FIELDS_FILTER = 'LABEL_FIELDS_FILTER'; export const LABEL_FIELDS_BREAKDOWN = 'LABEL_FIELDS_BREAKDOWN'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts index 2781c26954234..139f9fe67c751 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts @@ -16,7 +16,7 @@ import { } from './constants/elasticsearch_fieldnames'; import { buildExistsFilter, buildPhrasesFilter } from './utils'; import { sampleAttributeKpi } from './test_data/sample_attribute_kpi'; -import { RECORDS_FIELD, REPORT_METRIC_FIELD, ReportTypes } from './constants'; +import { RECORDS_FIELD, REPORT_METRIC_FIELD, PERCENTILE_RANKS, ReportTypes } from './constants'; describe('Lens Attribute', () => { mockAppIndexPattern(); @@ -75,6 +75,63 @@ describe('Lens Attribute', () => { expect(lnsAttrKpi.getJSON()).toEqual(sampleAttributeKpi); }); + it('should return expected json for percentile breakdowns', function () { + const seriesConfigKpi = getDefaultConfigs({ + reportType: ReportTypes.KPI, + dataType: 'ux', + indexPattern: mockIndexPattern, + }); + + const lnsAttrKpi = new LensAttributes([ + { + filters: [], + seriesConfig: seriesConfigKpi, + time: { + from: 'now-1h', + to: 'now', + }, + indexPattern: mockIndexPattern, + name: 'ux-series-1', + breakdown: 'percentile', + reportDefinitions: {}, + selectedMetricField: 'transaction.duration.us', + color: '#54b399', + }, + ]); + + expect(lnsAttrKpi.getJSON().state.datasourceStates.indexpattern.layers.layer0.columns).toEqual({ + 'x-axis-column-layer0': { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { + interval: 'auto', + }, + scale: 'interval', + sourceField: '@timestamp', + }, + ...PERCENTILE_RANKS.reduce((acc: Record<string, any>, rank, index) => { + acc[`y-axis-column-${index === 0 ? 'layer' + index : index}`] = { + dataType: 'number', + filter: { + language: 'kuery', + query: 'transaction.type: page-load and processor.event: transaction', + }, + isBucketed: false, + label: `${rank} percentile of page load time`, + operationType: 'percentile', + params: { + percentile: Number(rank.slice(0, 2)), + }, + scale: 'ratio', + sourceField: 'transaction.duration.us', + }; + return acc; + }, {}), + }); + }); + it('should return main y axis', function () { expect(lnsAttr.getMainYAxis(layerConfig, 'layer0', '')).toEqual({ dataType: 'number', @@ -413,7 +470,7 @@ describe('Lens Attribute', () => { yConfig: [{ color: 'green', forAccessor: 'y-axis-column-layer0' }], }, ], - legend: { isVisible: true, position: 'right' }, + legend: { isVisible: true, showSingleSeries: true, position: 'right' }, preferredSeriesType: 'line', tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, valueLabels: 'hide', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index fa5a8beb0087d..e3dab3c4e91f0 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -37,6 +37,8 @@ import { REPORT_METRIC_FIELD, RECORDS_FIELD, RECORDS_PERCENTAGE_FIELD, + PERCENTILE, + PERCENTILE_RANKS, ReportTypes, } from './constants'; import { ColumnFilter, SeriesConfig, UrlFilter, URLReportDefinition } from '../types'; @@ -249,6 +251,30 @@ export class LensAttributes { }; } + getPercentileBreakdowns( + layerConfig: LayerConfig, + columnFilter?: string + ): Record<string, FieldBasedIndexPatternColumn> { + const yAxisColumns = layerConfig.seriesConfig.yAxisColumns; + const { sourceField: mainSourceField, label: mainLabel } = yAxisColumns[0]; + const lensColumns: Record<string, FieldBasedIndexPatternColumn> = {}; + + // start at 1, because main y axis will have the first percentile breakdown + for (let i = 1; i < PERCENTILE_RANKS.length; i++) { + lensColumns[`y-axis-column-${i}`] = { + ...this.getColumnBasedOnType({ + sourceField: mainSourceField!, + operationType: PERCENTILE_RANKS[i], + label: mainLabel, + layerConfig, + colIndex: i, + }), + filter: { query: columnFilter || '', language: 'kuery' }, + }; + } + return lensColumns; + } + getPercentileNumberColumn( sourceField: string, percentileValue: string, @@ -258,7 +284,7 @@ export class LensAttributes { ...buildNumberColumn(sourceField), label: i18n.translate('xpack.observability.expView.columns.label', { defaultMessage: '{percentileValue} percentile of {sourceField}', - values: { sourceField: seriesConfig.labels[sourceField], percentileValue }, + values: { sourceField: seriesConfig.labels[sourceField]?.toLowerCase(), percentileValue }, }), operationType: 'percentile', params: { percentile: Number(percentileValue.split('th')[0]) }, @@ -328,6 +354,7 @@ export class LensAttributes { layerConfig: LayerConfig; colIndex?: number; }) { + const { breakdown, seriesConfig } = layerConfig; const { fieldMeta, columnType, fieldName, columnLabel, timeScale, columnFilters } = this.getFieldMeta(sourceField, layerConfig); @@ -348,6 +375,18 @@ export class LensAttributes { if (fieldType === 'date') { return this.getDateHistogramColumn(fieldName); } + + if (fieldType === 'number' && breakdown === PERCENTILE) { + return { + ...this.getPercentileNumberColumn( + fieldName, + operationType || PERCENTILE_RANKS[0], + seriesConfig! + ), + filter: colIndex !== undefined ? columnFilters?.[colIndex] : undefined, + }; + } + if (fieldType === 'number') { return this.getNumberColumn({ sourceField: fieldName, @@ -395,6 +434,7 @@ export class LensAttributes { } getMainYAxis(layerConfig: LayerConfig, layerId: string, columnFilter: string) { + const { breakdown } = layerConfig; const { sourceField, operationType, label } = layerConfig.seriesConfig.yAxisColumns[0]; if (sourceField === RECORDS_PERCENTAGE_FIELD) { @@ -407,7 +447,7 @@ export class LensAttributes { return this.getColumnBasedOnType({ sourceField, - operationType, + operationType: breakdown === PERCENTILE ? PERCENTILE_RANKS[0] : operationType, label, layerConfig, colIndex: 0, @@ -415,6 +455,7 @@ export class LensAttributes { } getChildYAxises(layerConfig: LayerConfig, layerId?: string, columnFilter?: string) { + const { breakdown } = layerConfig; const lensColumns: Record<string, FieldBasedIndexPatternColumn | SumIndexPatternColumn> = {}; const yAxisColumns = layerConfig.seriesConfig.yAxisColumns; const { sourceField: mainSourceField, label: mainLabel } = yAxisColumns[0]; @@ -424,7 +465,10 @@ export class LensAttributes { .supportingColumns; } - // 1 means there is only main y axis + if (yAxisColumns.length === 1 && breakdown === PERCENTILE) { + return this.getPercentileBreakdowns(layerConfig, columnFilter); + } + if (yAxisColumns.length === 1) { return lensColumns; } @@ -574,7 +618,7 @@ export class LensAttributes { layers[layerId] = { columnOrder: [ `x-axis-column-${layerId}`, - ...(breakdown && sourceField !== USE_BREAK_DOWN_COLUMN + ...(breakdown && sourceField !== USE_BREAK_DOWN_COLUMN && breakdown !== PERCENTILE ? [`breakdown-column-${layerId}`] : []), `y-axis-column-${layerId}`, @@ -588,7 +632,7 @@ export class LensAttributes { filter: { query: columnFilter, language: 'kuery' }, ...(timeShift ? { timeShift } : {}), }, - ...(breakdown && sourceField !== USE_BREAK_DOWN_COLUMN + ...(breakdown && sourceField !== USE_BREAK_DOWN_COLUMN && breakdown !== PERCENTILE ? // do nothing since this will be used a x axis source { [`breakdown-column-${layerId}`]: this.getBreakdownColumn({ @@ -610,7 +654,7 @@ export class LensAttributes { getXyState(): XYState { return { - legend: { isVisible: true, position: 'right' }, + legend: { isVisible: true, showSingleSeries: true, position: 'right' }, valueLabels: 'hide', fittingFunction: 'Linear', curveType: 'CURVE_MONOTONE_X' as XYCurveType, @@ -636,6 +680,7 @@ export class LensAttributes { ], xAccessor: `x-axis-column-layer${index}`, ...(layerConfig.breakdown && + layerConfig.breakdown !== PERCENTILE && layerConfig.seriesConfig.xAxisColumn.sourceField !== USE_BREAK_DOWN_COLUMN ? { splitAccessor: `breakdown-column-layer${index}` } : {}), diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts index de4f6b2198dbd..000e50d7b3a52 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts @@ -13,6 +13,7 @@ import { OPERATION_COLUMN, RECORDS_FIELD, REPORT_METRIC_FIELD, + PERCENTILE, ReportTypes, } from '../constants'; import { buildPhraseFilter } from '../utils'; @@ -81,6 +82,7 @@ export function getKPITrendsLensConfig({ indexPattern }: ConfigProps): SeriesCon USER_AGENT_OS, CLIENT_GEO_COUNTRY_NAME, USER_AGENT_DEVICE, + PERCENTILE, LABEL_FIELDS_BREAKDOWN, ], baseFilters: [ 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 65b43a83a8fb5..6df9cdcd0503a 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 @@ -6,7 +6,13 @@ */ import { ConfigProps, SeriesConfig } from '../../types'; -import { FieldLabels, OPERATION_COLUMN, REPORT_METRIC_FIELD, ReportTypes } from '../constants'; +import { + FieldLabels, + OPERATION_COLUMN, + REPORT_METRIC_FIELD, + PERCENTILE, + ReportTypes, +} from '../constants'; import { CLS_LABEL, DCL_LABEL, @@ -44,7 +50,7 @@ export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): SeriesCon ], hasOperationType: false, filterFields: ['observer.geo.name', 'monitor.type', 'tags'], - breakdownFields: ['observer.geo.name', 'monitor.type', 'monitor.name'], + breakdownFields: ['observer.geo.name', 'monitor.type', 'monitor.name', PERCENTILE], baseFilters: [], palette: { type: 'palette', name: 'status' }, definitionFields: ['monitor.name', 'url.full'], @@ -98,6 +104,6 @@ export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): SeriesCon columnType: OPERATION_COLUMN, }, ], - labels: { ...FieldLabels }, + labels: { ...FieldLabels, [SUMMARY_UP]: UP_LABEL, [SUMMARY_DOWN]: DOWN_LABEL }, }; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts index 7e0ea1e575481..8254a5a816921 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts @@ -187,6 +187,7 @@ export const sampleAttribute = { ], legend: { isVisible: true, + showSingleSeries: true, position: 'right', }, preferredSeriesType: 'line', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts index dff3d6b3ad5ef..adc6d4bb14462 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts @@ -134,6 +134,7 @@ export const sampleAttributeCoreWebVital = { ], legend: { isVisible: true, + showSingleSeries: true, position: 'right', }, preferredSeriesType: 'line', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts index 6ed9b4face6e3..8fbda9f6adc52 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts @@ -89,6 +89,7 @@ export const sampleAttributeKpi = { ], legend: { isVisible: true, + showSingleSeries: true, position: 'right', }, preferredSeriesType: 'line', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx index 83a7ac1ae17dc..8a766075ef8d2 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx @@ -65,7 +65,7 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { case 'mobile': const resultApm = await getDataHandler('apm')?.hasData(); hasDataT = Boolean(resultApm?.hasData); - indices = resultApm?.indices['apm_oss.transactionIndices']; + indices = resultApm?.indices.transaction; break; } setHasAppData((prevState) => ({ ...prevState, [dataType]: hasDataT })); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.test.tsx index cb683119384d9..8ed279ace28f6 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.test.tsx @@ -10,6 +10,7 @@ import { fireEvent, screen } from '@testing-library/react'; import { Breakdowns } from './breakdowns'; import { mockIndexPattern, mockUxSeries, render } from '../../rtl_helpers'; import { getDefaultConfigs } from '../../configurations/default_configs'; +import { RECORDS_FIELD } from '../../configurations/constants'; import { USER_AGENT_OS } from '../../configurations/constants/elasticsearch_fieldnames'; describe('Breakdowns', function () { @@ -56,6 +57,26 @@ describe('Breakdowns', function () { expect(setSeries).toHaveBeenCalledTimes(1); }); + it('does not show percentile breakdown for records metrics', function () { + const kpiConfig = getDefaultConfigs({ + reportType: 'kpi-over-time', + indexPattern: mockIndexPattern, + dataType: 'ux', + }); + + render( + <Breakdowns + seriesId={0} + seriesConfig={kpiConfig} + series={{ ...mockUxSeries, selectedMetricField: RECORDS_FIELD }} + /> + ); + + fireEvent.click(screen.getByTestId('seriesBreakdown')); + + expect(screen.queryByText('Percentile')).not.toBeInTheDocument(); + }); + it('should disable breakdowns when a different series has a breakdown', function () { const initSeries = { data: [mockUxSeries, { ...mockUxSeries, breakdown: undefined }], diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.tsx index 7964abdeeddc5..a235cbd8852ad 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/breakdown/breakdowns.tsx @@ -10,7 +10,12 @@ import styled from 'styled-components'; import { EuiSuperSelect, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useSeriesStorage } from '../../hooks/use_series_storage'; -import { LABEL_FIELDS_BREAKDOWN, USE_BREAK_DOWN_COLUMN } from '../../configurations/constants'; +import { + LABEL_FIELDS_BREAKDOWN, + USE_BREAK_DOWN_COLUMN, + RECORDS_FIELD, + PERCENTILE, +} from '../../configurations/constants'; import { SeriesConfig, SeriesUrl } from '../../types'; interface Props { @@ -51,6 +56,7 @@ export function Breakdowns({ seriesConfig, seriesId, series }: Props) { } const hasUseBreakdownColumn = seriesConfig.xAxisColumn.sourceField === USE_BREAK_DOWN_COLUMN; + const isRecordsMetric = series.selectedMetricField === RECORDS_FIELD; const items = seriesConfig.breakdownFields.map((breakdown) => ({ id: breakdown, @@ -64,11 +70,13 @@ export function Breakdowns({ seriesConfig, seriesId, series }: Props) { }); } - const options = items.map(({ id, label }) => ({ - inputDisplay: label, - value: id, - dropdownDisplay: label, - })); + const options = items + .map(({ id, label }) => ({ + inputDisplay: label, + value: id, + dropdownDisplay: label, + })) + .filter(({ value }) => !(value === PERCENTILE && isRecordsMetric)); let valueOfSelected = selectedBreakdown || (hasUseBreakdownColumn ? options[0].value : NO_BREAKDOWN); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.test.tsx new file mode 100644 index 0000000000000..83958840f63d9 --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.test.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { screen } from '@testing-library/react'; +import { ExpandedSeriesRow } from './expanded_series_row'; +import { mockIndexPattern, mockUxSeries, render } from '../rtl_helpers'; +import { getDefaultConfigs } from '../configurations/default_configs'; +import { PERCENTILE } from '../configurations/constants'; + +describe('ExpandedSeriesRow', function () { + const dataViewSeries = getDefaultConfigs({ + reportType: 'kpi-over-time', + indexPattern: mockIndexPattern, + dataType: 'ux', + }); + + it('should render properly', async function () { + render(<ExpandedSeriesRow seriesId={0} seriesConfig={dataViewSeries} series={mockUxSeries} />); + + expect(screen.getByText('Breakdown by')).toBeInTheDocument(); + expect(screen.getByText('Operation')).toBeInTheDocument(); + }); + + it('should not display operation field when percentile breakdowns are applied', async function () { + render( + <ExpandedSeriesRow + seriesId={0} + seriesConfig={{ ...dataViewSeries, hasOperationType: true }} + series={{ ...mockUxSeries, breakdown: PERCENTILE }} + /> + ); + + expect(screen.queryByText('Operation')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.tsx index ac71f4ff5abe0..180be1ac0414f 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/expanded_series_row.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiHorizontalRule } from '@elastic/eui'; import { SeriesConfig, SeriesUrl } from '../types'; +import { PERCENTILE } from '../configurations/constants'; import { ReportDefinitionCol } from './columns/report_definition_col'; import { OperationTypeSelect } from './columns/operation_type_select'; import { parseCustomFieldName } from '../configurations/lens_attributes'; @@ -42,6 +43,9 @@ export function ExpandedSeriesRow(seriesProps: Props) { const columnType = getColumnType(seriesConfig, selectedMetricField); + // if the breakdown field is percentiles, we can't apply further operations + const hasPercentileBreakdown = series.breakdown === PERCENTILE; + return ( <div style={{ width: '100%' }}> <EuiFlexGroup gutterSize="xs"> @@ -69,7 +73,7 @@ export function ExpandedSeriesRow(seriesProps: Props) { </EuiFlexGroup> </EuiFormRow> </EuiFlexItem> - {(hasOperationType || columnType === 'operation') && ( + {(hasOperationType || (columnType === 'operation' && !hasPercentileBreakdown)) && ( <EuiFlexItem grow={1}> <EuiFormRow label={OPERATION_LABEL}> <OperationTypeSelect diff --git a/x-pack/plugins/observability/public/context/has_data_context.test.tsx b/x-pack/plugins/observability/public/context/has_data_context.test.tsx index 36f7bfb990222..a586a8bf0bcce 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.test.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.test.tsx @@ -24,10 +24,7 @@ import { act } from '@testing-library/react'; const relativeStart = '2020-10-08T06:00:00.000Z'; const relativeEnd = '2020-10-08T07:00:00.000Z'; -const sampleAPMIndices = { - // eslint-disable-next-line @typescript-eslint/naming-convention - 'apm_oss.transactionIndices': 'apm-*', -} as ApmIndicesConfig; +const sampleAPMIndices = { transaction: 'apm-*' } as ApmIndicesConfig; function wrapper({ children }: { children: React.ReactElement }) { const history = createMemoryHistory(); diff --git a/x-pack/plugins/observability/public/data_handler.test.ts b/x-pack/plugins/observability/public/data_handler.test.ts index e0b8494d4dbed..2beae5d111f7d 100644 --- a/x-pack/plugins/observability/public/data_handler.test.ts +++ b/x-pack/plugins/observability/public/data_handler.test.ts @@ -9,10 +9,7 @@ import { registerDataHandler, getDataHandler } from './data_handler'; import moment from 'moment'; import { ApmIndicesConfig } from '../common/typings'; -const sampleAPMIndices = { - // eslint-disable-next-line @typescript-eslint/naming-convention - 'apm_oss.transactionIndices': 'apm-*', -} as ApmIndicesConfig; +const sampleAPMIndices = { transaction: 'apm-*' } as ApmIndicesConfig; const params = { absoluteTime: { diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx index 3c389a0ee20b2..506b919b16416 100644 --- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx @@ -36,10 +36,7 @@ function unregisterAll() { unregisterDataHandler({ appName: 'synthetics' }); } -const sampleAPMIndices = { - // eslint-disable-next-line @typescript-eslint/naming-convention - 'apm_oss.transactionIndices': 'apm-*', -} as ApmIndicesConfig; +const sampleAPMIndices = { transaction: 'apm-*' } as ApmIndicesConfig; const withCore = makeDecorator({ name: 'withCore', diff --git a/x-pack/plugins/reporting/common/constants.ts b/x-pack/plugins/reporting/common/constants.ts index 3fb02677dd981..cafab65677ee4 100644 --- a/x-pack/plugins/reporting/common/constants.ts +++ b/x-pack/plugins/reporting/common/constants.ts @@ -59,6 +59,11 @@ export const LAYOUT_TYPES = { PRINT: 'print', }; +export const DEFAULT_VIEWPORT = { + width: 1950, + height: 1200, +}; + // Export Type Definitions export const CSV_REPORT_TYPE = 'CSV'; export const CSV_JOB_TYPE = 'csv_searchsource'; diff --git a/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap b/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap index 3d49e8e695f9b..9c72de2bf0ed8 100644 --- a/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap +++ b/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap @@ -82,6 +82,7 @@ Array [ "reactNode": <React.Fragment> <EuiCallOut color="danger" + data-test-errorText="this is the failed report error" iconType="alert" size="m" title="The reporting job failed" diff --git a/x-pack/plugins/reporting/public/management/__snapshots__/report_listing.test.tsx.snap b/x-pack/plugins/reporting/public/management/__snapshots__/report_listing.test.tsx.snap index 70cd9e414e85d..f025a4b7dac55 100644 --- a/x-pack/plugins/reporting/public/management/__snapshots__/report_listing.test.tsx.snap +++ b/x-pack/plugins/reporting/public/management/__snapshots__/report_listing.test.tsx.snap @@ -33,7 +33,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` checked={false} compressed={false} disabled={false} - id="_selection_column-checkbox_generated-id" + id="_selection_column-checkbox_generated-id_mobile" indeterminate={false} label="Select all rows" onChange={[Function]} @@ -46,7 +46,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` checked={false} className="euiCheckbox__input" disabled={false} - id="_selection_column-checkbox_generated-id" + id="_selection_column-checkbox_generated-id_mobile" onChange={[Function]} type="checkbox" /> @@ -55,7 +55,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` /> <label className="euiCheckbox__label" - htmlFor="_selection_column-checkbox_generated-id" + htmlFor="_selection_column-checkbox_generated-id_mobile" > Select all rows </label> @@ -76,13 +76,13 @@ exports[`ReportListing Report job listing with some items 1`] = ` </div> </EuiTableHeaderMobile> <EuiTable - id="generated-id" + id="__table_generated-id" responsive={true} tableLayout="fixed" > <table className="euiTable euiTable--responsive" - id="generated-id" + id="__table_generated-id" tabIndex={-1} > <EuiScreenReaderOnly> @@ -122,7 +122,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` compressed={false} data-test-subj="checkboxSelectAll" disabled={false} - id="_selection_column-checkbox_generated-id" + id="_selection_column-checkbox_generated-id_desktop" indeterminate={false} label={null} onChange={[Function]} @@ -137,7 +137,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` className="euiCheckbox__input" data-test-subj="checkboxSelectAll" disabled={false} - id="_selection_column-checkbox_generated-id" + id="_selection_column-checkbox_generated-id_desktop" onChange={[Function]} type="checkbox" /> @@ -10370,7 +10370,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` </EuiTable> </div> <PaginationBar - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-label={ <EuiI18n default="Pagination for preceding table: {tableCaption}" @@ -10403,7 +10403,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` </EuiSpacer> <EuiTablePagination activePage={0} - aria-controls="generated-id" + aria-controls="__table_generated-id" hidePerPageOptions={true} itemsPerPage={10} itemsPerPageOptions={ @@ -10440,7 +10440,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` > <EuiPagination activePage={0} - aria-controls="generated-id" + aria-controls="__table_generated-id" onPageClick={[Function]} pageCount={2} > @@ -10500,7 +10500,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` > <PaginationButtonWrapper activePage={0} - ariaControls="generated-id" + ariaControls="__table_generated-id" key="0" pageCount={2} pageIndex={0} @@ -10510,7 +10510,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` className="euiPagination__item" > <EuiPaginationButton - aria-controls="generated-id" + aria-controls="__table_generated-id" hideOnMobile={true} isActive={true} onClick={[Function]} @@ -10537,19 +10537,19 @@ exports[`ReportListing Report job listing with some items 1`] = ` } > <EuiButtonEmpty - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-current={true} aria-label="Page 1 of 2" className="euiPaginationButton euiPaginationButton-isActive euiPaginationButton--hideOnMobile" color="text" data-test-subj="pagination-button-0" - href="#generated-id" + href="#__table_generated-id" isDisabled={true} onClick={[Function]} size="s" > <button - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-current={true} aria-label="Page 1 of 2" className="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiButtonEmpty-isDisabled euiPaginationButton euiPaginationButton-isActive euiPaginationButton--hideOnMobile" @@ -10587,7 +10587,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` </PaginationButtonWrapper> <PaginationButtonWrapper activePage={0} - ariaControls="generated-id" + ariaControls="__table_generated-id" key="1" pageCount={2} pageIndex={1} @@ -10597,7 +10597,7 @@ exports[`ReportListing Report job listing with some items 1`] = ` className="euiPagination__item" > <EuiPaginationButton - aria-controls="generated-id" + aria-controls="__table_generated-id" hideOnMobile={true} isActive={false} onClick={[Function]} @@ -10624,22 +10624,22 @@ exports[`ReportListing Report job listing with some items 1`] = ` } > <EuiButtonEmpty - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-label="Page 2 of 2" className="euiPaginationButton euiPaginationButton--hideOnMobile" color="text" data-test-subj="pagination-button-1" - href="#generated-id" + href="#__table_generated-id" isDisabled={false} onClick={[Function]} size="s" > <a - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-label="Page 2 of 2" className="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton euiPaginationButton--hideOnMobile" data-test-subj="pagination-button-1" - href="#generated-id" + href="#__table_generated-id" onClick={[Function]} rel="noreferrer" > @@ -10685,20 +10685,20 @@ exports[`ReportListing Report job listing with some items 1`] = ` token="euiPagination.disabledNextPage" > <EuiButtonIcon - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-label="Next page, 2" color="text" data-test-subj="pagination-button-next" - href="#generated-id" + href="#__table_generated-id" iconType="arrowRight" onClick={[Function]} > <a - aria-controls="generated-id" + aria-controls="__table_generated-id" aria-label="Next page, 2" className="euiButtonIcon euiButtonIcon--text euiButtonIcon--empty euiButtonIcon--xSmall" data-test-subj="pagination-button-next" - href="#generated-id" + href="#__table_generated-id" onClick={[Function]} rel="noreferrer" > diff --git a/x-pack/plugins/reporting/public/management/report_listing.test.tsx b/x-pack/plugins/reporting/public/management/report_listing.test.tsx index bdb8bdbbe5d5e..5e80c2d666c23 100644 --- a/x-pack/plugins/reporting/public/management/report_listing.test.tsx +++ b/x-pack/plugins/reporting/public/management/report_listing.test.tsx @@ -26,12 +26,6 @@ import { Job } from '../lib/job'; import { InternalApiClientProvider, ReportingAPIClient } from '../lib/reporting_api_client'; import { KibanaContextProvider } from '../shared_imports'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - interface PayloadMock { payload: Omit<ReportApiJSON['payload'], 'browserTimezone' | 'version' | 'layout'>; } diff --git a/x-pack/plugins/reporting/public/notifier/job_failure.tsx b/x-pack/plugins/reporting/public/notifier/job_failure.tsx index e892a1f93a7c2..7775afc4d9f82 100644 --- a/x-pack/plugins/reporting/public/notifier/job_failure.tsx +++ b/x-pack/plugins/reporting/public/notifier/job_failure.tsx @@ -35,6 +35,7 @@ export const getFailureToast = ( })} color="danger" iconType="alert" + data-test-errorText={errorText} > {errorText} </EuiCallOut> diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts index bedf310725ae2..a4fe1835ce5f7 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts @@ -107,7 +107,7 @@ describe('GetCsvReportPanelAction', () => { columns: [], objectType: 'downloadCsv', searchSource: {}, - title: undefined, + title: '', version: '7.15.0', }); }); @@ -144,7 +144,7 @@ describe('GetCsvReportPanelAction', () => { columns: ['column_a', 'column_b'], objectType: 'downloadCsv', searchSource: { testData: 'testDataValue' }, - title: undefined, + title: '', version: '7.15.0', }); }); diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index 115d7599c6bc8..fbfaeab9bc4f2 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -122,7 +122,7 @@ export class ReportingCsvPanelAction implements ActionDefinition<ActionContext> const immediateJobParams = this.apiClient.getDecoratedJobParams({ searchSource: getSearchSource(true), columns, - title: savedSearch.title, + title: savedSearch.title || '', objectType: 'downloadCsv', // FIXME: added for typescript, but immediate download job does not need objectType }); diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/args.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/args.ts index 3659e05bc3618..07ae13fa31849 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/args.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/args.ts @@ -6,18 +6,17 @@ */ import { CaptureConfig } from '../../../../server/types'; +import { DEFAULT_VIEWPORT } from '../../../../common/constants'; -type ViewportConfig = CaptureConfig['viewport']; type BrowserConfig = CaptureConfig['browser']['chromium']; interface LaunchArgs { userDataDir: string; - viewport: ViewportConfig; disableSandbox: BrowserConfig['disableSandbox']; proxy: BrowserConfig['proxy']; } -export const args = ({ userDataDir, viewport, disableSandbox, proxy: proxyConfig }: LaunchArgs) => { +export const args = ({ userDataDir, disableSandbox, proxy: proxyConfig }: LaunchArgs) => { const flags = [ // Disable built-in Google Translate service '--disable-translate', @@ -45,7 +44,7 @@ export const args = ({ userDataDir, viewport, disableSandbox, proxy: proxyConfig // NOTE: setting the window size does NOT set the viewport size: viewport and window size are different. // The viewport may later need to be resized depending on the position of the clip area. // These numbers come from the job parameters, so this is a close guess. - `--window-size=${Math.floor(viewport.width)},${Math.floor(viewport.height)}`, + `--window-size=${Math.floor(DEFAULT_VIEWPORT.width)},${Math.floor(DEFAULT_VIEWPORT.height)}`, // allow screenshot clip region to go outside of the viewport `--mainFrameClipsContent=false`, ]; diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts index a0487421a9a0d..688dd425fa8f3 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts @@ -5,10 +5,10 @@ * 2.0. */ -import apm from 'elastic-apm-node'; import { i18n } from '@kbn/i18n'; import { getDataPath } from '@kbn/utils'; import del from 'del'; +import apm from 'elastic-apm-node'; import fs from 'fs'; import path from 'path'; import puppeteer from 'puppeteer'; @@ -23,7 +23,7 @@ import { LevelLogger } from '../../../lib'; import { safeChildProcess } from '../../safe_child_process'; import { HeadlessChromiumDriver } from '../driver'; import { args } from './args'; -import { Metrics, getMetrics } from './metrics'; +import { getMetrics, Metrics } from './metrics'; // Puppeteer type definitions do not match the documentation. // See https://pptr.dev/#?product=Puppeteer&version=v8.0.0&show=api-puppeteerlaunchoptions @@ -38,14 +38,13 @@ declare module 'puppeteer' { } type BrowserConfig = CaptureConfig['browser']['chromium']; -type ViewportConfig = CaptureConfig['viewport']; export class HeadlessChromiumDriverFactory { private binaryPath: string; private captureConfig: CaptureConfig; private browserConfig: BrowserConfig; private userDataDir: string; - private getChromiumArgs: (viewport: ViewportConfig) => string[]; + private getChromiumArgs: () => string[]; private core: ReportingCore; constructor(core: ReportingCore, binaryPath: string, logger: LevelLogger) { @@ -60,10 +59,9 @@ export class HeadlessChromiumDriverFactory { } this.userDataDir = fs.mkdtempSync(path.join(getDataPath(), 'chromium-')); - this.getChromiumArgs = (viewport: ViewportConfig) => + this.getChromiumArgs = () => args({ userDataDir: this.userDataDir, - viewport, disableSandbox: this.browserConfig.disableSandbox, proxy: this.browserConfig.proxy, }); @@ -75,7 +73,7 @@ export class HeadlessChromiumDriverFactory { * Return an observable to objects which will drive screenshot capture for a page */ createPage( - { viewport, browserTimezone }: { viewport: ViewportConfig; browserTimezone?: string }, + { browserTimezone }: { browserTimezone?: string }, pLogger: LevelLogger ): Rx.Observable<{ driver: HeadlessChromiumDriver; exit$: Rx.Observable<never> }> { // FIXME: 'create' is deprecated @@ -83,7 +81,7 @@ export class HeadlessChromiumDriverFactory { const logger = pLogger.clone(['browser-driver']); logger.info(`Creating browser page driver`); - const chromiumArgs = this.getChromiumArgs(viewport); + const chromiumArgs = this.getChromiumArgs(); logger.debug(`Chromium launch args set to: ${chromiumArgs}`); let browser: puppeteer.Browser; diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts index aa27e46b85acb..1a739488bf6ed 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts @@ -74,7 +74,6 @@ export const browserStartLogs = ( const kbnArgs = args({ userDataDir, - viewport: { width: 800, height: 600 }, disableSandbox, proxy, }); diff --git a/x-pack/plugins/reporting/server/config/index.ts b/x-pack/plugins/reporting/server/config/index.ts index f8fa47bc00bb0..45a71d05165ba 100644 --- a/x-pack/plugins/reporting/server/config/index.ts +++ b/x-pack/plugins/reporting/server/config/index.ts @@ -20,6 +20,7 @@ export const config: PluginConfigDescriptor<ReportingConfigType> = { unused('capture.browser.chromium.maxScreenshotDimension'), // unused since 7.8 unused('poll.jobCompletionNotifier.intervalErrorMultiplier'), // unused since 7.10 unused('poll.jobsRefresh.intervalErrorMultiplier'), // unused since 7.10 + unused('capture.viewport'), // deprecated as unused since 7.16 (settings, fromPath, addDeprecation) => { const reporting = get(settings, fromPath); if (reporting?.index) { diff --git a/x-pack/plugins/reporting/server/config/schema.test.ts b/x-pack/plugins/reporting/server/config/schema.test.ts index 0b2e2cac6ff7c..6ad7d03bd1a8f 100644 --- a/x-pack/plugins/reporting/server/config/schema.test.ts +++ b/x-pack/plugins/reporting/server/config/schema.test.ts @@ -63,10 +63,6 @@ describe('Reporting Config Schema', () => { "renderComplete": "PT30S", "waitForElements": "PT30S", }, - "viewport": Object { - "height": 1200, - "width": 1950, - }, "zoom": 2, }, "csv": Object { @@ -168,10 +164,6 @@ describe('Reporting Config Schema', () => { "renderComplete": "PT30S", "waitForElements": "PT30S", }, - "viewport": Object { - "height": 1200, - "width": 1950, - }, "zoom": 2, }, "csv": Object { diff --git a/x-pack/plugins/reporting/server/config/schema.ts b/x-pack/plugins/reporting/server/config/schema.ts index 832cf6c28e1fa..5b15260be06cb 100644 --- a/x-pack/plugins/reporting/server/config/schema.ts +++ b/x-pack/plugins/reporting/server/config/schema.ts @@ -74,10 +74,6 @@ const CaptureSchema = schema.object({ }), }), zoom: schema.number({ defaultValue: 2 }), - viewport: schema.object({ - width: schema.number({ defaultValue: 1950 }), - height: schema.number({ defaultValue: 1200 }), - }), loadDelay: schema.oneOf([schema.number(), schema.duration()], { defaultValue: moment.duration({ seconds: 3 }), }), diff --git a/x-pack/plugins/reporting/server/export_types/common/generate_png.ts b/x-pack/plugins/reporting/server/export_types/common/generate_png.ts index b6f9c3fba8ea9..85e9513c4a618 100644 --- a/x-pack/plugins/reporting/server/export_types/common/generate_png.ts +++ b/x-pack/plugins/reporting/server/export_types/common/generate_png.ts @@ -54,6 +54,9 @@ export async function generatePngObservableFactory(reporting: ReportingCore) { if (current.error) { found.push(current.error.message); } + if (current.renderErrors) { + found.push(...current.renderErrors); + } return found; }, [] as string[]), })), diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts index f393661e4c490..1902c4ed0272e 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts @@ -75,6 +75,7 @@ const mockSearchSourceGetFieldDefault = jest.fn().mockImplementation((key: strin getByName: jest.fn().mockImplementation(() => []), getByType: jest.fn().mockImplementation(() => []), }, + metaFields: ['_id', '_index', '_type', '_score'], getFormatterForField: jest.fn(), }; } diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts index c269677ae930d..6c2989d54309d 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts @@ -356,7 +356,7 @@ export class CsvGenerator { let table: Datatable | undefined; try { - table = tabifyDocs(results, index, { shallow: true, meta: true }); + table = tabifyDocs(results, index, { shallow: true }); } catch (err) { this.logger.error(err); } diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/lib/generate_pdf.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/lib/generate_pdf.ts index 74b013edc8cab..dce6ea678bded 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/lib/generate_pdf.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/lib/generate_pdf.ts @@ -108,6 +108,9 @@ export async function generatePdfObservableFactory(reporting: ReportingCore) { if (current.error) { found.push(current.error.message); } + if (current.renderErrors) { + found.push(...current.renderErrors); + } return found; }, [] as string[]), }; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts index 9fb31a1104279..b44e2ca4441eb 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts @@ -120,6 +120,9 @@ export async function generatePdfObservableFactory(reporting: ReportingCore) { if (current.error) { found.push(current.error.message); } + if (current.renderErrors) { + found.push(...current.renderErrors); + } return found; }, [] as string[]), }; diff --git a/x-pack/plugins/reporting/server/lib/layouts/create_layout.test.ts b/x-pack/plugins/reporting/server/lib/layouts/create_layout.test.ts index be9a06267a7c8..aebd20451b834 100644 --- a/x-pack/plugins/reporting/server/lib/layouts/create_layout.test.ts +++ b/x-pack/plugins/reporting/server/lib/layouts/create_layout.test.ts @@ -32,6 +32,8 @@ describe('Create Layout', () => { "selectors": Object { "itemsCountAttribute": "data-shared-items-count", "renderComplete": "[data-shared-item]", + "renderError": "[data-render-error]", + "renderErrorAttribute": "data-render-error", "screenshot": "[data-shared-items-container]", "timefilterDurationAttribute": "data-shared-timefilter-duration", }, @@ -63,10 +65,16 @@ describe('Create Layout', () => { "selectors": Object { "itemsCountAttribute": "data-shared-items-count", "renderComplete": "[data-shared-item]", + "renderError": "[data-render-error]", + "renderErrorAttribute": "data-render-error", "screenshot": "[data-shared-item]", "timefilterDurationAttribute": "data-shared-timefilter-duration", }, "useReportingBranding": true, + "viewport": Object { + "height": 1200, + "width": 1950, + }, } `); }); @@ -87,6 +95,8 @@ describe('Create Layout', () => { "selectors": Object { "itemsCountAttribute": "data-shared-items-count", "renderComplete": "[data-shared-item]", + "renderError": "[data-render-error]", + "renderErrorAttribute": "data-render-error", "screenshot": "[data-shared-items-container]", "timefilterDurationAttribute": "data-shared-timefilter-duration", }, diff --git a/x-pack/plugins/reporting/server/lib/layouts/index.ts b/x-pack/plugins/reporting/server/lib/layouts/index.ts index 9729508f955c7..b721565b1d771 100644 --- a/x-pack/plugins/reporting/server/lib/layouts/index.ts +++ b/x-pack/plugins/reporting/server/lib/layouts/index.ts @@ -13,6 +13,8 @@ import type { Layout } from './layout'; export interface LayoutSelectorDictionary { screenshot: string; renderComplete: string; + renderError: string; + renderErrorAttribute: string; itemsCountAttribute: string; timefilterDurationAttribute: string; } @@ -33,6 +35,8 @@ export const LayoutTypes = { export const getDefaultLayoutSelectors = (): LayoutSelectorDictionary => ({ screenshot: '[data-shared-items-container]', renderComplete: '[data-shared-item]', + renderError: '[data-render-error]', + renderErrorAttribute: 'data-render-error', itemsCountAttribute: 'data-shared-items-count', timefilterDurationAttribute: 'data-shared-timefilter-duration', }); diff --git a/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts b/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts index 03feb36496349..0849f8850f91d 100644 --- a/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts +++ b/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts @@ -9,7 +9,7 @@ import path from 'path'; import { PageOrientation, PredefinedPageSize } from 'pdfmake/interfaces'; import { EvaluateFn, SerializableOrJSHandle } from 'puppeteer'; import { LevelLogger } from '../'; -import { LAYOUT_TYPES } from '../../../common/constants'; +import { DEFAULT_VIEWPORT, LAYOUT_TYPES } from '../../../common/constants'; import { Size } from '../../../common/types'; import { HeadlessChromiumDriver } from '../../browsers'; import { CaptureConfig } from '../../types'; @@ -22,7 +22,8 @@ export class PrintLayout extends Layout implements LayoutInstance { screenshot: '[data-shared-item]', // override '[data-shared-items-container]' }; public readonly groupCount = 2; - private captureConfig: CaptureConfig; + private readonly captureConfig: CaptureConfig; + private readonly viewport = DEFAULT_VIEWPORT; constructor(captureConfig: CaptureConfig) { super(LAYOUT_TYPES.PRINT); @@ -34,7 +35,7 @@ export class PrintLayout extends Layout implements LayoutInstance { } public getBrowserViewport() { - return this.captureConfig.viewport; + return this.viewport; } public getBrowserZoom() { @@ -44,8 +45,8 @@ export class PrintLayout extends Layout implements LayoutInstance { public getViewport(itemsCount: number) { return { zoom: this.captureConfig.zoom, - width: this.captureConfig.viewport.width, - height: this.captureConfig.viewport.height * itemsCount, + width: this.viewport.width, + height: this.viewport.height * itemsCount, }; } @@ -56,8 +57,8 @@ export class PrintLayout extends Layout implements LayoutInstance { logger.debug('positioning elements'); const elementSize: Size = { - width: this.captureConfig.viewport.width / this.captureConfig.zoom, - height: this.captureConfig.viewport.height / this.captureConfig.zoom, + width: this.viewport.width / this.captureConfig.zoom, + height: this.viewport.height / this.captureConfig.zoom, }; const evalOptions: { fn: EvaluateFn; args: SerializableOrJSHandle[] } = { fn: (selector: string, height: number, width: number) => { diff --git a/x-pack/plugins/reporting/server/lib/puid.d.ts b/x-pack/plugins/reporting/server/lib/puid.d.ts index 2cf7dad67d06e..4ac240157971f 100644 --- a/x-pack/plugins/reporting/server/lib/puid.d.ts +++ b/x-pack/plugins/reporting/server/lib/puid.d.ts @@ -6,7 +6,7 @@ */ declare module 'puid' { - declare class Puid { + class Puid { generate(): string; } diff --git a/x-pack/plugins/reporting/server/lib/screenshots/constants.ts b/x-pack/plugins/reporting/server/lib/screenshots/constants.ts index 226f5bc52d8d9..c62b910630874 100644 --- a/x-pack/plugins/reporting/server/lib/screenshots/constants.ts +++ b/x-pack/plugins/reporting/server/lib/screenshots/constants.ts @@ -11,6 +11,7 @@ export const DEFAULT_PAGELOAD_SELECTOR = `.${APP_WRAPPER_CLASS}`; export const CONTEXT_GETNUMBEROFITEMS = 'GetNumberOfItems'; export const CONTEXT_INJECTCSS = 'InjectCss'; export const CONTEXT_WAITFORRENDER = 'WaitForRender'; +export const CONTEXT_GETRENDERERRORS = 'GetVisualisationsRenderErrors'; export const CONTEXT_GETTIMERANGE = 'GetTimeRange'; export const CONTEXT_ELEMENTATTRIBUTES = 'ElementPositionAndAttributes'; export const CONTEXT_WAITFORELEMENTSTOBEINDOM = 'WaitForElementsToBeInDOM'; diff --git a/x-pack/plugins/reporting/server/lib/screenshots/get_render_errors.test.ts b/x-pack/plugins/reporting/server/lib/screenshots/get_render_errors.test.ts new file mode 100644 index 0000000000000..d29c0936bfceb --- /dev/null +++ b/x-pack/plugins/reporting/server/lib/screenshots/get_render_errors.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 { HeadlessChromiumDriver } from '../../browsers'; +import { + createMockBrowserDriverFactory, + createMockConfig, + createMockConfigSchema, + createMockLayoutInstance, + createMockLevelLogger, + createMockReportingCore, +} from '../../test_helpers'; +import { CaptureConfig } from '../../types'; +import { LayoutInstance } from '../layouts'; +import { LevelLogger } from '../level_logger'; +import { getRenderErrors } from './get_render_errors'; + +describe('getRenderErrors', () => { + let captureConfig: CaptureConfig; + let layout: LayoutInstance; + let logger: jest.Mocked<LevelLogger>; + let browser: HeadlessChromiumDriver; + + beforeEach(async () => { + const schema = createMockConfigSchema(); + const config = createMockConfig(schema); + const core = await createMockReportingCore(schema); + + captureConfig = config.get('capture'); + layout = createMockLayoutInstance(captureConfig); + logger = createMockLevelLogger(); + + await createMockBrowserDriverFactory(core, logger, { + evaluate: jest.fn( + async <T extends (...args: unknown[]) => unknown>({ + fn, + args, + }: { + fn: T; + args: Parameters<T>; + }) => fn(...args) + ), + getCreatePage: (driver) => { + browser = driver; + + return jest.fn(); + }, + }); + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('should extract the error messages', async () => { + document.body.innerHTML = ` + <div dataRenderErrorSelector="a test error" /> + <div dataRenderErrorSelector="a test error" /> + <div dataRenderErrorSelector="a test error" /> + <div dataRenderErrorSelector="a test error" /> + `; + + await expect(getRenderErrors(browser, layout, logger)).resolves.toEqual([ + 'a test error', + 'a test error', + 'a test error', + 'a test error', + ]); + }); + + it('should extract the error messages, even when there are none', async () => { + document.body.innerHTML = ` + <renderedSelector /> + `; + + await expect(getRenderErrors(browser, layout, logger)).resolves.toEqual(undefined); + }); +}); diff --git a/x-pack/plugins/reporting/server/lib/screenshots/get_render_errors.ts b/x-pack/plugins/reporting/server/lib/screenshots/get_render_errors.ts new file mode 100644 index 0000000000000..ded4ed6238872 --- /dev/null +++ b/x-pack/plugins/reporting/server/lib/screenshots/get_render_errors.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 type { HeadlessChromiumDriver } from '../../browsers'; +import type { LayoutInstance } from '../layouts'; +import { LevelLogger, startTrace } from '../'; +import { CONTEXT_GETRENDERERRORS } from './constants'; + +export const getRenderErrors = async ( + browser: HeadlessChromiumDriver, + layout: LayoutInstance, + logger: LevelLogger +): Promise<undefined | string[]> => { + const endTrace = startTrace('get_render_errors', 'read'); + logger.debug('reading render errors'); + const errorsFound: undefined | string[] = await browser.evaluate( + { + fn: (errorSelector, errorAttribute) => { + const visualizations: Element[] = Array.from(document.querySelectorAll(errorSelector)); + const errors: string[] = []; + + visualizations.forEach((visualization) => { + const errorMessage = visualization.getAttribute(errorAttribute); + if (errorMessage) { + errors.push(errorMessage); + } + }); + + return errors.length ? errors : undefined; + }, + args: [layout.selectors.renderError, layout.selectors.renderErrorAttribute], + }, + { context: CONTEXT_GETRENDERERRORS }, + logger + ); + endTrace(); + + if (errorsFound?.length) { + logger.warning( + i18n.translate('xpack.reporting.screencapture.renderErrorsFound', { + defaultMessage: 'Found {count} error messages. See report object for more information.', + values: { count: errorsFound.length }, + }) + ); + } + + return errorsFound; +}; diff --git a/x-pack/plugins/reporting/server/lib/screenshots/index.ts b/x-pack/plugins/reporting/server/lib/screenshots/index.ts index 6615cbdc79c94..1ca8b5e00fee4 100644 --- a/x-pack/plugins/reporting/server/lib/screenshots/index.ts +++ b/x-pack/plugins/reporting/server/lib/screenshots/index.ts @@ -53,5 +53,12 @@ export interface ScreenshotResults { timeRange: string | null; screenshots: Screenshot[]; error?: Error; + + /** + * Individual visualizations might encounter errors at runtime. If there are any they are added to this + * field. Any text captured here is intended to be shown to the user for debugging purposes, reporting + * does no further sanitization on these strings. + */ + renderErrors?: string[]; elementsPositionAndAttributes?: ElementsPositionAndAttribute[]; // NOTE: for testing } diff --git a/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts b/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts index 901abe7a7b3fb..c33bdad44f9e7 100644 --- a/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts +++ b/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts @@ -98,6 +98,7 @@ describe('Screenshot Observable Pipeline', () => { }, ], "error": undefined, + "renderErrors": undefined, "screenshots": Array [ Object { "data": Object { @@ -172,6 +173,7 @@ describe('Screenshot Observable Pipeline', () => { }, ], "error": undefined, + "renderErrors": undefined, "screenshots": Array [ Object { "data": Object { @@ -223,6 +225,7 @@ describe('Screenshot Observable Pipeline', () => { }, ], "error": undefined, + "renderErrors": undefined, "screenshots": Array [ Object { "data": Object { @@ -312,6 +315,7 @@ describe('Screenshot Observable Pipeline', () => { }, ], "error": [Error: An error occurred when trying to read the page for visualization panel info. You may need to increase 'xpack.reporting.capture.timeouts.waitForElements'. Error: Mock error!], + "renderErrors": undefined, "screenshots": Array [ Object { "data": Object { @@ -354,6 +358,7 @@ describe('Screenshot Observable Pipeline', () => { }, ], "error": [Error: An error occurred when trying to read the page for visualization panel info. You may need to increase 'xpack.reporting.capture.timeouts.waitForElements'. Error: Mock error!], + "renderErrors": undefined, "screenshots": Array [ Object { "data": Object { @@ -460,6 +465,7 @@ describe('Screenshot Observable Pipeline', () => { }, ], "error": undefined, + "renderErrors": undefined, "screenshots": Array [ Object { "data": Object { diff --git a/x-pack/plugins/reporting/server/lib/screenshots/observable.ts b/x-pack/plugins/reporting/server/lib/screenshots/observable.ts index b7791cb2924e5..b8fecdc91a3f2 100644 --- a/x-pack/plugins/reporting/server/lib/screenshots/observable.ts +++ b/x-pack/plugins/reporting/server/lib/screenshots/observable.ts @@ -17,6 +17,7 @@ import { getElementPositionAndAttributes } from './get_element_position_data'; import { getNumberOfItems } from './get_number_of_items'; import { getScreenshots } from './get_screenshots'; import { getTimeRange } from './get_time_range'; +import { getRenderErrors } from './get_render_errors'; import { injectCustomCss } from './inject_css'; import { openUrl } from './open_url'; import { waitForRenderComplete } from './wait_for_render'; @@ -28,6 +29,7 @@ const DEFAULT_SCREENSHOT_CLIP_WIDTH = 1800; interface ScreenSetupData { elementsPositionAndAttributes: ElementsPositionAndAttribute[] | null; timeRange: string | null; + renderErrors?: string[]; error?: Error; } @@ -45,10 +47,7 @@ export function getScreenshots$( const apmTrans = apm.startTransaction(`reporting screenshot pipeline`, 'reporting'); const apmCreatePage = apmTrans?.startSpan('create_page', 'wait'); - const create$ = browserDriverFactory.createPage( - { viewport: layout.getBrowserViewport(), browserTimezone }, - logger - ); + const create$ = browserDriverFactory.createPage({ browserTimezone }, logger); return create$.pipe( mergeMap(({ driver, exit$ }) => { @@ -101,16 +100,22 @@ export function getScreenshots$( return await Promise.all([ getTimeRange(driver, layout, logger), getElementPositionAndAttributes(driver, layout, logger), - ]).then(([timeRange, elementsPositionAndAttributes]) => ({ + getRenderErrors(driver, layout, logger), + ]).then(([timeRange, elementsPositionAndAttributes, renderErrors]) => ({ elementsPositionAndAttributes, timeRange, + renderErrors, })); }), catchError((err) => { checkPageIsOpen(driver); // if browser has closed, throw a relevant error about it logger.error(err); - return Rx.of({ elementsPositionAndAttributes: null, timeRange: null, error: err }); + return Rx.of({ + elementsPositionAndAttributes: null, + timeRange: null, + error: err, + }); }) ); @@ -123,11 +128,12 @@ export function getScreenshots$( ? data.elementsPositionAndAttributes : getDefaultElementPosition(layout.getViewport(1)); const screenshots = await getScreenshots(driver, elements, logger); - const { timeRange, error: setupError } = data; + const { timeRange, error: setupError, renderErrors } = data; return { timeRange, screenshots, error: setupError, + renderErrors, elementsPositionAndAttributes: elements, }; }) diff --git a/x-pack/plugins/reporting/server/test_helpers/create_mock_browserdriverfactory.ts b/x-pack/plugins/reporting/server/test_helpers/create_mock_browserdriverfactory.ts index 8cd0a63f860e8..d42fb73b447a5 100644 --- a/x-pack/plugins/reporting/server/test_helpers/create_mock_browserdriverfactory.ts +++ b/x-pack/plugins/reporting/server/test_helpers/create_mock_browserdriverfactory.ts @@ -78,6 +78,9 @@ mockBrowserEvaluate.mockImplementation(() => { if (mockCall === contexts.CONTEXT_ELEMENTATTRIBUTES) { return Promise.resolve(getMockElementsPositionAndAttributes('Default Mock Title', 'Default ')); } + if (mockCall === contexts.CONTEXT_GETRENDERERRORS) { + return Promise.resolve(); + } throw new Error(mockCall); }); const mockScreenshot = jest.fn(async () => Buffer.from('screenshot')); @@ -114,7 +117,6 @@ export const createMockBrowserDriverFactory = async ( autoDownload: false, }, networkPolicy: { enabled: true, rules: [] }, - viewport: { width: 800, height: 600 }, loadDelay: moment.duration(2, 's'), zoom: 2, maxAttempts: 1, diff --git a/x-pack/plugins/reporting/server/test_helpers/create_mock_layoutinstance.ts b/x-pack/plugins/reporting/server/test_helpers/create_mock_layoutinstance.ts index 0edbea9311db2..e9b94c3c98bec 100644 --- a/x-pack/plugins/reporting/server/test_helpers/create_mock_layoutinstance.ts +++ b/x-pack/plugins/reporting/server/test_helpers/create_mock_layoutinstance.ts @@ -18,6 +18,8 @@ export const createMockLayoutInstance = (captureConfig: CaptureConfig) => { renderComplete: 'renderedSelector', itemsCountAttribute: 'itemsSelector', screenshot: 'screenshotSelector', + renderError: '[dataRenderErrorSelector]', + renderErrorAttribute: 'dataRenderErrorSelector', timefilterDurationAttribute: 'timefilterDurationSelector', }; return mockLayout; diff --git a/x-pack/plugins/rule_registry/server/config.ts b/x-pack/plugins/rule_registry/server/config.ts index 62f29a9e06294..f112a99e59eaa 100644 --- a/x-pack/plugins/rule_registry/server/config.ts +++ b/x-pack/plugins/rule_registry/server/config.ts @@ -9,7 +9,10 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { PluginConfigDescriptor } from 'src/core/server'; export const config: PluginConfigDescriptor = { - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], + deprecations: ({ deprecate, unused }) => [ + deprecate('enabled', '8.0.0'), + unused('unsafe.indexUpgrade.enabled'), + ], schema: schema.object({ enabled: schema.boolean({ defaultValue: true }), write: schema.object({ diff --git a/x-pack/plugins/rule_registry/server/index.ts b/x-pack/plugins/rule_registry/server/index.ts index b287e6a3e4688..5331ab86be982 100644 --- a/x-pack/plugins/rule_registry/server/index.ts +++ b/x-pack/plugins/rule_registry/server/index.ts @@ -32,7 +32,7 @@ export { LifecycleAlertServices, createLifecycleExecutor, } from './utils/create_lifecycle_executor'; -export { createPersistenceRuleTypeFactory } from './utils/create_persistence_rule_type_factory'; +export { createPersistenceRuleTypeWrapper } from './utils/create_persistence_rule_type_wrapper'; export * from './utils/persistence_types'; export type { AlertsClient } from './alert_data_client/alerts_client'; diff --git a/x-pack/plugins/rule_registry/server/plugin.ts b/x-pack/plugins/rule_registry/server/plugin.ts index 5d1994cfd3e6d..b68f3eeb10669 100644 --- a/x-pack/plugins/rule_registry/server/plugin.ts +++ b/x-pack/plugins/rule_registry/server/plugin.ts @@ -104,7 +104,6 @@ export class RuleRegistryPlugin logger, kibanaVersion, isWriteEnabled: isWriteEnabled(this.config, this.legacyConfig), - isIndexUpgradeEnabled: this.config.unsafe.indexUpgrade.enabled, getClusterClient: async () => { const deps = await startDependencies; return deps.core.elasticsearch.client.asInternalUser; diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts index 89ae479132de5..2755021e235a8 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts @@ -5,13 +5,18 @@ * 2.0. */ +import { BulkRequest } from '@elastic/elasticsearch/api/types'; import { ResponseError } from '@elastic/elasticsearch/lib/errors'; import { Either, isLeft } from 'fp-ts/lib/Either'; import { ElasticsearchClient } from 'kibana/server'; +import { Logger } from 'kibana/server'; import { IndexPatternsFetcher } from '../../../../../src/plugins/data/server'; -import { RuleDataWriteDisabledError } from '../rule_data_plugin_service/errors'; +import { + RuleDataWriteDisabledError, + RuleDataWriterInitializationError, +} from '../rule_data_plugin_service/errors'; import { IndexInfo } from '../rule_data_plugin_service/index_info'; import { ResourceInstaller } from '../rule_data_plugin_service/resource_installer'; import { IRuleDataClient, IRuleDataReader, IRuleDataWriter } from './types'; @@ -22,12 +27,21 @@ interface ConstructorOptions { isWriteEnabled: boolean; waitUntilReadyForReading: Promise<WaitResult>; waitUntilReadyForWriting: Promise<WaitResult>; + logger: Logger; } export type WaitResult = Either<Error, ElasticsearchClient>; export class RuleDataClient implements IRuleDataClient { - constructor(private readonly options: ConstructorOptions) {} + private _isWriteEnabled: boolean = false; + + // Writers cached by namespace + private writerCache: Map<string, IRuleDataWriter>; + + constructor(private readonly options: ConstructorOptions) { + this.writeEnabled = this.options.isWriteEnabled; + this.writerCache = new Map(); + } public get indexName(): string { return this.options.indexInfo.baseName; @@ -37,8 +51,16 @@ export class RuleDataClient implements IRuleDataClient { return this.options.indexInfo.kibanaVersion; } + private get writeEnabled(): boolean { + return this._isWriteEnabled; + } + + private set writeEnabled(isEnabled: boolean) { + this._isWriteEnabled = isEnabled; + } + public isWriteEnabled(): boolean { - return this.options.isWriteEnabled; + return this.writeEnabled; } public getReader(options: { namespace?: string } = {}): IRuleDataReader { @@ -95,62 +117,89 @@ export class RuleDataClient implements IRuleDataClient { } public getWriter(options: { namespace?: string } = {}): IRuleDataWriter { - const { indexInfo, resourceInstaller } = this.options; - const namespace = options.namespace || 'default'; + const cachedWriter = this.writerCache.get(namespace); + + // There is no cached writer, so we'll install / update the namespace specific resources now. + if (!cachedWriter) { + const writerForNamespace = this.initializeWriter(namespace); + this.writerCache.set(namespace, writerForNamespace); + return writerForNamespace; + } else { + return cachedWriter; + } + } + + private initializeWriter(namespace: string): IRuleDataWriter { + const isWriteEnabled = () => this.writeEnabled; + const turnOffWrite = () => (this.writeEnabled = false); + + const { indexInfo, resourceInstaller } = this.options; const alias = indexInfo.getPrimaryAlias(namespace); - const isWriteEnabled = this.isWriteEnabled(); - const waitUntilReady = async () => { - const result = await this.options.waitUntilReadyForWriting; - if (isLeft(result)) { - throw result.left; + // Wait until both index and namespace level resources have been installed / updated. + const prepareForWriting = async () => { + if (!isWriteEnabled()) { + throw new RuleDataWriteDisabledError(); + } + + const indexLevelResourcesResult = await this.options.waitUntilReadyForWriting; + + if (isLeft(indexLevelResourcesResult)) { + throw new RuleDataWriterInitializationError( + 'index', + indexInfo.indexOptions.registrationContext, + indexLevelResourcesResult.left + ); } else { - return result.right; + try { + await resourceInstaller.installAndUpdateNamespaceLevelResources(indexInfo, namespace); + return indexLevelResourcesResult.right; + } catch (e) { + throw new RuleDataWriterInitializationError( + 'namespace', + indexInfo.indexOptions.registrationContext, + e + ); + } } }; - return { - bulk: async (request) => { - if (!isWriteEnabled) { - throw new RuleDataWriteDisabledError(); - } + const prepareForWritingResult = prepareForWriting(); - const clusterClient = await waitUntilReady(); + return { + bulk: async (request: BulkRequest) => { + return prepareForWritingResult + .then((clusterClient) => { + const requestWithDefaultParameters = { + ...request, + require_alias: true, + index: alias, + }; - const requestWithDefaultParameters = { - ...request, - require_alias: true, - index: alias, - }; - - return clusterClient.bulk(requestWithDefaultParameters).then((response) => { - if (response.body.errors) { - if ( - response.body.items.length > 0 && - (response.body.items.every( - (item) => item.index?.error?.type === 'index_not_found_exception' - ) || - response.body.items.every( - (item) => item.index?.error?.type === 'illegal_argument_exception' - )) - ) { - return resourceInstaller - .installNamespaceLevelResources(indexInfo, namespace) - .then(() => { - return clusterClient.bulk(requestWithDefaultParameters).then((retryResponse) => { - if (retryResponse.body.errors) { - throw new ResponseError(retryResponse); - } - return retryResponse; - }); - }); + return clusterClient.bulk(requestWithDefaultParameters).then((response) => { + if (response.body.errors) { + const error = new ResponseError(response); + throw error; + } + return response; + }); + }) + .catch((error) => { + if (error instanceof RuleDataWriterInitializationError) { + this.options.logger.error(error); + this.options.logger.error( + `The writer for the Rule Data Client for the ${indexInfo.indexOptions.registrationContext} registration context was not initialized properly, bulk() cannot continue, and writing will be disabled.` + ); + turnOffWrite(); + } else if (error instanceof RuleDataWriteDisabledError) { + this.options.logger.debug(`Writing is disabled, bulk() will not write any data.`); + } else { + this.options.logger.error(error); } - const error = new ResponseError(response); - throw error; - } - return response; - }); + + return undefined; + }); }, }; } diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/types.ts b/x-pack/plugins/rule_registry/server/rule_data_client/types.ts index 0595dbeea6dc6..7c05945a98b10 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/types.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/types.ts @@ -35,5 +35,5 @@ export interface IRuleDataReader { } export interface IRuleDataWriter { - bulk(request: BulkRequest): Promise<ApiResponse<BulkResponse>>; + bulk(request: BulkRequest): Promise<ApiResponse<BulkResponse> | undefined>; } diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts index cb5dcf8e8ae76..fe8d3b3b18d9d 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts @@ -5,6 +5,7 @@ * 2.0. */ +/* eslint-disable max-classes-per-file */ export class RuleDataWriteDisabledError extends Error { constructor(message?: string) { super(message); @@ -12,3 +13,16 @@ export class RuleDataWriteDisabledError extends Error { this.name = 'RuleDataWriteDisabledError'; } } + +export class RuleDataWriterInitializationError extends Error { + constructor( + resourceType: 'index' | 'namespace', + registrationContext: string, + error: string | Error + ) { + super(`There has been a catastrophic error trying to install ${resourceType} level resources for the following registration context: ${registrationContext}. + This may have been due to a non-additive change to the mappings, removal and type changes are not permitted. Full error: ${error.toString()}`); + Object.setPrototypeOf(this, new.target.prototype); + this.name = 'RuleDataWriterInitializationError'; + } +} diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts index e10bb6382ab24..160261642ff25 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts @@ -20,7 +20,6 @@ import { ecsComponentTemplate } from '../../common/assets/component_templates/ec import { defaultLifecyclePolicy } from '../../common/assets/lifecycle_policies/default_lifecycle_policy'; import { IndexInfo } from './index_info'; -import { incrementIndexName } from './utils'; const INSTALLATION_TIMEOUT = 20 * 60 * 1000; // 20 minutes @@ -29,7 +28,6 @@ interface ConstructorOptions { getClusterClient: () => Promise<ElasticsearchClient>; logger: Logger; isWriteEnabled: boolean; - isIndexUpgradeEnabled: boolean; } export class ResourceInstaller { @@ -111,12 +109,10 @@ export class ResourceInstaller { * Installs index-level resources shared between all namespaces of this index: * - custom ILM policy if it was provided * - component templates - * - attempts to update mappings of existing concrete indices */ public async installIndexLevelResources(indexInfo: IndexInfo): Promise<void> { await this.installWithTimeout(`resources for index ${indexInfo.baseName}`, async () => { const { componentTemplates, ilmPolicy } = indexInfo.indexOptions; - const { isIndexUpgradeEnabled } = this.options; if (ilmPolicy != null) { await this.createOrUpdateLifecyclePolicy({ @@ -139,35 +135,30 @@ export class ResourceInstaller { }); }) ); - - if (isIndexUpgradeEnabled) { - // TODO: Update all existing namespaced index templates matching this index' base name - - await this.updateIndexMappings(indexInfo); - } }); } - private async updateIndexMappings(indexInfo: IndexInfo) { + private async updateIndexMappings(indexInfo: IndexInfo, namespace: string) { const { logger } = this.options; const aliases = indexInfo.basePattern; - const backingIndices = indexInfo.getPatternForBackingIndices(); + const backingIndices = indexInfo.getPatternForBackingIndices(namespace); logger.debug(`Updating mappings of existing concrete indices for ${indexInfo.baseName}`); // Find all concrete indices for all namespaces of the index. const concreteIndices = await this.fetchConcreteIndices(aliases, backingIndices); - const concreteWriteIndices = concreteIndices.filter((item) => item.isWriteIndex); - - // Update mappings of the found write indices. - await Promise.all(concreteWriteIndices.map((item) => this.updateAliasWriteIndexMapping(item))); + // Update mappings of the found indices. + await Promise.all(concreteIndices.map((item) => this.updateAliasWriteIndexMapping(item))); } + // NOTE / IMPORTANT: Please note this will update the mappings of backing indices but + // *not* the settings. This is due to the fact settings can be classed as dynamic and static, + // and static updates will fail on an index that isn't closed. New settings *will* be applied as part + // of the ILM policy rollovers. More info: https://github.com/elastic/kibana/pull/113389#issuecomment-940152654 private async updateAliasWriteIndexMapping({ index, alias }: ConcreteIndexInfo) { const { logger, getClusterClient } = this.options; const clusterClient = await getClusterClient(); - const simulatedIndexMapping = await clusterClient.indices.simulateIndexTemplate({ name: index, }); @@ -180,35 +171,8 @@ export class ResourceInstaller { }); return; } catch (err) { - if (err.meta?.body?.error?.type !== 'illegal_argument_exception') { - /** - * We skip the rollover if we catch anything except for illegal_argument_exception - that's the error - * returned by ES when the mapping update contains a conflicting field definition (e.g., a field changes types). - * We expect to get that error for some mapping changes we might make, and in those cases, - * we want to continue to rollover the index. Other errors are unexpected. - */ - logger.error(`Failed to PUT mapping for alias ${alias}: ${err.message}`); - return; - } - const newIndexName = incrementIndexName(index); - if (newIndexName == null) { - logger.error(`Failed to increment write index name for alias: ${alias}`); - return; - } - try { - await clusterClient.indices.rollover({ - alias, - new_index: newIndexName, - }); - } catch (e) { - /** - * If we catch resource_already_exists_exception, that means that the index has been - * rolled over already — nothing to do for us in this case. - */ - if (e?.meta?.body?.error?.type !== 'resource_already_exists_exception') { - logger.error(`Failed to rollover index for alias ${alias}: ${e.message}`); - } - } + logger.error(`Failed to PUT mapping for alias ${alias}: ${err.message}`); + throw err; } } @@ -216,11 +180,12 @@ export class ResourceInstaller { // Namespace-level resources /** - * Installs resources tied to concrete namespace of an index: + * Installs and updates resources tied to concrete namespace of an index: * - namespaced index template + * - Index mappings for existing concrete indices * - concrete index (write target) if it doesn't exist */ - public async installNamespaceLevelResources( + public async installAndUpdateNamespaceLevelResources( indexInfo: IndexInfo, namespace: string ): Promise<void> { @@ -230,15 +195,19 @@ export class ResourceInstaller { logger.info(`Installing namespace-level resources and creating concrete index for ${alias}`); + // Install / update the index template + await this.installNamespacedIndexTemplate(indexInfo, namespace); + // Update index mappings for indices matching this namespace. + await this.updateIndexMappings(indexInfo, namespace); + // If we find a concrete backing index which is the write index for the alias here, we shouldn't // be making a new concrete index. We return early because we don't need a new write target. const indexExists = await this.checkIfConcreteWriteIndexExists(indexInfo, namespace); if (indexExists) { return; + } else { + await this.createConcreteWriteIndex(indexInfo, namespace); } - - await this.installNamespacedIndexTemplate(indexInfo, namespace); - await this.createConcreteWriteIndex(indexInfo, namespace); } private async checkIfConcreteWriteIndexExists( diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts index c69677b091c9c..0617bc0a820ac 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts @@ -22,7 +22,6 @@ interface ConstructorOptions { logger: Logger; kibanaVersion: string; isWriteEnabled: boolean; - isIndexUpgradeEnabled: boolean; } /** @@ -44,7 +43,6 @@ export class RuleDataPluginService { getClusterClient: options.getClusterClient, logger: options.logger, isWriteEnabled: options.isWriteEnabled, - isIndexUpgradeEnabled: options.isIndexUpgradeEnabled, }); this.installCommonResources = Promise.resolve(right('ok')); @@ -154,6 +152,7 @@ export class RuleDataPluginService { isWriteEnabled: this.isWriteEnabled(), waitUntilReadyForReading, waitUntilReadyForWriting, + logger: this.options.logger, }); } diff --git a/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_factory.ts b/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts similarity index 91% rename from x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_factory.ts rename to x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts index 837d0378703f7..86b6cf72ed1f1 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_factory.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts @@ -7,9 +7,9 @@ import { ALERT_INSTANCE_ID, VERSION } from '@kbn/rule-data-utils'; import { getCommonAlertFields } from './get_common_alert_fields'; -import { CreatePersistenceRuleTypeFactory } from './persistence_types'; +import { CreatePersistenceRuleTypeWrapper } from './persistence_types'; -export const createPersistenceRuleTypeFactory: CreatePersistenceRuleTypeFactory = +export const createPersistenceRuleTypeWrapper: CreatePersistenceRuleTypeWrapper = ({ logger, ruleDataClient }) => (type) => { return { diff --git a/x-pack/plugins/rule_registry/server/utils/persistence_types.ts b/x-pack/plugins/rule_registry/server/utils/persistence_types.ts index 11607909a2e0f..5da05d9956d7f 100644 --- a/x-pack/plugins/rule_registry/server/utils/persistence_types.ts +++ b/x-pack/plugins/rule_registry/server/utils/persistence_types.ts @@ -8,43 +8,59 @@ import { ApiResponse } from '@elastic/elasticsearch'; import { BulkResponse } from '@elastic/elasticsearch/api/types'; import { Logger } from '@kbn/logging'; -import { ESSearchRequest } from 'src/core/types/elasticsearch'; import { + AlertExecutorOptions, AlertInstanceContext, AlertInstanceState, + AlertType, AlertTypeParams, AlertTypeState, } from '../../../alerting/server'; +import { WithoutReservedActionGroups } from '../../../alerting/common'; import { IRuleDataClient } from '../rule_data_client'; -import { AlertTypeWithExecutor } from '../types'; -export type PersistenceAlertService< - TState extends AlertInstanceState = never, - TContext extends AlertInstanceContext = never, - TActionGroupIds extends string = never -> = ( +export type PersistenceAlertService = ( alerts: Array<{ id: string; fields: Record<string, unknown>; }>, refresh: boolean | 'wait_for' -) => Promise<ApiResponse<BulkResponse, unknown>>; +) => Promise<ApiResponse<BulkResponse, unknown> | undefined>; -export type PersistenceAlertQueryService = ( - query: ESSearchRequest -) => Promise<Array<Record<string, unknown>>>; -export interface PersistenceServices<TAlertInstanceContext extends AlertInstanceContext = {}> { - alertWithPersistence: PersistenceAlertService<TAlertInstanceContext>; +export interface PersistenceServices { + alertWithPersistence: PersistenceAlertService; } -export type CreatePersistenceRuleTypeFactory = (options: { +export type PersistenceAlertType< + TParams extends AlertTypeParams, + TState extends AlertTypeState, + TInstanceContext extends AlertInstanceContext = {}, + TActionGroupIds extends string = never +> = Omit< + AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>, + 'executor' +> & { + executor: ( + options: AlertExecutorOptions< + TParams, + TState, + AlertInstanceState, + TInstanceContext, + WithoutReservedActionGroups<TActionGroupIds, never> + > & { + services: PersistenceServices; + } + ) => Promise<TState | void>; +}; + +export type CreatePersistenceRuleTypeWrapper = (options: { ruleDataClient: IRuleDataClient; logger: Logger; }) => < - TState extends AlertTypeState, TParams extends AlertTypeParams, - TServices extends PersistenceServices<TAlertInstanceContext>, - TAlertInstanceContext extends AlertInstanceContext = {} + TState extends AlertTypeState, + TInstanceContext extends AlertInstanceContext = {}, + TActionGroupIds extends string = never >( - type: AlertTypeWithExecutor<TState, TParams, TAlertInstanceContext, TServices> -) => AlertTypeWithExecutor<TState, TParams, TAlertInstanceContext, TServices>; + type: PersistenceAlertType<TParams, TState, TInstanceContext, TActionGroupIds> +) => AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>; diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index d2120faf09dfb..51511fad90b30 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -301,6 +301,7 @@ export const NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS = [ '.swimlane', '.webhook', '.servicenow', + '.servicenow-sir', '.jira', '.resilient', '.teams', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index a9f7d96f1eb2e..3933d7e39275e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -35,6 +35,18 @@ export type Description = t.TypeOf<typeof description>; export const descriptionOrUndefined = t.union([description, t.undefined]); export type DescriptionOrUndefined = t.TypeOf<typeof descriptionOrUndefined>; +// outcome is a property of the saved object resolve api +// will tell us info about the rule after 8.0 migrations +export const outcome = t.union([ + t.literal('exactMatch'), + t.literal('aliasMatch'), + t.literal('conflict'), +]); +export type Outcome = t.TypeOf<typeof outcome>; + +export const alias_target_id = t.string; +export type AliasTargetId = t.TypeOf<typeof alias_target_id>; + export const enabled = t.boolean; export type Enabled = t.TypeOf<typeof enabled>; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts index 719337a231c1c..12e72fb6fc697 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts @@ -58,6 +58,8 @@ import { tags, interval, enabled, + outcome, + alias_target_id, updated_at, updated_by, created_at, @@ -150,6 +152,8 @@ const baseParams = { building_block_type, note, license, + outcome, + alias_target_id, output_index, timeline_id, timeline_title, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts index 247829d5b9e7a..ac9329c3870f1 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts @@ -70,6 +70,8 @@ import { last_failure_message, filters, meta, + outcome, + alias_target_id, note, building_block_type, license, @@ -174,6 +176,8 @@ export const partialRulesSchema = t.partial({ last_failure_message, filters, meta, + outcome, + alias_target_id, index, namespace, note, diff --git a/x-pack/plugins/security_solution/common/endpoint/constants.ts b/x-pack/plugins/security_solution/common/endpoint/constants.ts index c7949299c68db..6e9123da2dd9b 100644 --- a/x-pack/plugins/security_solution/common/endpoint/constants.ts +++ b/x-pack/plugins/security_solution/common/endpoint/constants.ts @@ -5,8 +5,12 @@ * 2.0. */ -export const ENDPOINT_ACTIONS_INDEX = '.logs-endpoint.actions-default'; -export const ENDPOINT_ACTION_RESPONSES_INDEX = '.logs-endpoint.action.responses-default'; +/** endpoint data streams that are used for host isolation */ +/** for index patterns `.logs-endpoint.actions-* and .logs-endpoint.action.responses-*`*/ +export const ENDPOINT_ACTIONS_DS = '.logs-endpoint.actions'; +export const ENDPOINT_ACTIONS_INDEX = `${ENDPOINT_ACTIONS_DS}-default`; +export const ENDPOINT_ACTION_RESPONSES_DS = '.logs-endpoint.action.responses'; +export const ENDPOINT_ACTION_RESPONSES_INDEX = `${ENDPOINT_ACTIONS_DS}-default`; export const eventsIndexPattern = 'logs-endpoint.events.*'; export const alertsIndexPattern = 'logs-endpoint.alerts-*'; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts index 0a39e4ea351f0..dd4eeeab15cce 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts @@ -8,51 +8,7 @@ import { DeepPartial } from 'utility-types'; import { merge } from 'lodash'; import { BaseDataGenerator } from './base_data_generator'; -import { EndpointActionData, ISOLATION_ACTIONS } from '../types'; - -interface EcsError { - code: string; - id: string; - message: string; - stack_trace: string; - type: string; -} - -interface EndpointActionFields { - action_id: string; - data: EndpointActionData; -} - -interface ActionRequestFields { - expiration: string; - type: 'INPUT_ACTION'; - input_type: 'endpoint'; -} - -interface ActionResponseFields { - completed_at: string; - started_at: string; -} -export interface LogsEndpointAction { - '@timestamp': string; - agent: { - id: string | string[]; - }; - EndpointAction: EndpointActionFields & ActionRequestFields; - error?: EcsError; - user: { - id: string; - }; -} - -export interface LogsEndpointActionResponse { - '@timestamp': string; - agent: { - id: string | string[]; - }; - EndpointAction: EndpointActionFields & ActionResponseFields; - error?: EcsError; -} +import { ISOLATION_ACTIONS, LogsEndpointAction, LogsEndpointActionResponse } from '../types'; const ISOLATION_COMMANDS: ISOLATION_ACTIONS[] = ['isolate', 'unisolate']; @@ -66,7 +22,7 @@ export class EndpointActionGenerator extends BaseDataGenerator { agent: { id: [this.randomUUID()], }, - EndpointAction: { + EndpointActions: { action_id: this.randomUUID(), expiration: this.randomFutureDate(timeStamp), type: 'INPUT_ACTION', @@ -86,11 +42,11 @@ export class EndpointActionGenerator extends BaseDataGenerator { } generateIsolateAction(overrides: DeepPartial<LogsEndpointAction> = {}): LogsEndpointAction { - return merge(this.generate({ EndpointAction: { data: { command: 'isolate' } } }), overrides); + return merge(this.generate({ EndpointActions: { data: { command: 'isolate' } } }), overrides); } generateUnIsolateAction(overrides: DeepPartial<LogsEndpointAction> = {}): LogsEndpointAction { - return merge(this.generate({ EndpointAction: { data: { command: 'unisolate' } } }), overrides); + return merge(this.generate({ EndpointActions: { data: { command: 'unisolate' } } }), overrides); } /** Generates an endpoint action response */ @@ -105,7 +61,7 @@ export class EndpointActionGenerator extends BaseDataGenerator { agent: { id: this.randomUUID(), }, - EndpointAction: { + EndpointActions: { action_id: this.randomUUID(), completed_at: timeStamp.toISOString(), data: { diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_actions.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_actions.ts index bf46214b20f31..e4379271315dd 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_actions.ts @@ -7,12 +7,8 @@ import { Client } from '@elastic/elasticsearch'; import { DeleteByQueryResponse } from '@elastic/elasticsearch/api/types'; -import { HostMetadata } from '../types'; -import { - EndpointActionGenerator, - LogsEndpointAction, - LogsEndpointActionResponse, -} from '../data_generators/endpoint_action_generator'; +import { HostMetadata, LogsEndpointAction, LogsEndpointActionResponse } from '../types'; +import { EndpointActionGenerator } from '../data_generators/endpoint_action_generator'; import { wrapErrorAndRejectPromise } from './utils'; import { ENDPOINT_ACTIONS_INDEX, ENDPOINT_ACTION_RESPONSES_INDEX } from '../constants'; @@ -49,7 +45,7 @@ export const indexEndpointActionsForHost = async ( for (let i = 0; i < total; i++) { // create an action const action = endpointActionGenerator.generate({ - EndpointAction: { + EndpointActions: { data: { comment: 'data generator: this host is same as bad' }, }, }); @@ -66,9 +62,9 @@ export const indexEndpointActionsForHost = async ( // Create an action response for the above const actionResponse = endpointActionGenerator.generateResponse({ agent: { id: agentId }, - EndpointAction: { - action_id: action.EndpointAction.action_id, - data: action.EndpointAction.data, + EndpointActions: { + action_id: action.EndpointActions.action_id, + data: action.EndpointActions.data, }, }); @@ -174,7 +170,7 @@ export const deleteIndexedEndpointActions = async ( { terms: { action_id: indexedData.endpointActions.map( - (action) => action.EndpointAction.action_id + (action) => action.EndpointActions.action_id ), }, }, @@ -200,7 +196,7 @@ export const deleteIndexedEndpointActions = async ( { terms: { action_id: indexedData.endpointActionResponses.map( - (action) => action.EndpointAction.action_id + (action) => action.EndpointActions.action_id ), }, }, diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index c6d30825c21c9..bc46ca2f5b451 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -10,6 +10,50 @@ import { ActionStatusRequestSchema, HostIsolationRequestSchema } from '../schema export type ISOLATION_ACTIONS = 'isolate' | 'unisolate'; +interface EcsError { + code?: string; + id?: string; + message: string; + stack_trace?: string; + type?: string; +} + +interface EndpointActionFields { + action_id: string; + data: EndpointActionData; +} + +interface ActionRequestFields { + expiration: string; + type: 'INPUT_ACTION'; + input_type: 'endpoint'; +} + +interface ActionResponseFields { + completed_at: string; + started_at: string; +} +export interface LogsEndpointAction { + '@timestamp': string; + agent: { + id: string | string[]; + }; + EndpointActions: EndpointActionFields & ActionRequestFields; + error?: EcsError; + user: { + id: string; + }; +} + +export interface LogsEndpointActionResponse { + '@timestamp': string; + agent: { + id: string | string[]; + }; + EndpointActions: EndpointActionFields & ActionResponseFields; + error?: EcsError; +} + export interface EndpointActionData { command: ISOLATION_ACTIONS; comment?: string; diff --git a/x-pack/plugins/security_solution/cypress/downloads/test_exception_list.ndjson b/x-pack/plugins/security_solution/cypress/downloads/test_exception_list.ndjson new file mode 100644 index 0000000000000..54420eff29e0d --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/downloads/test_exception_list.ndjson @@ -0,0 +1,2 @@ +{"_version":"WzQyNjA0LDFd","created_at":"2021-10-14T01:30:22.034Z","created_by":"elastic","description":"Test exception list description","id":"4c65a230-2c8e-11ec-be1c-2bbdec602f88","immutable":false,"list_id":"test_exception_list","name":"Test exception list","namespace_type":"single","os_types":[],"tags":[],"tie_breaker_id":"b04983b4-1617-441c-bb6c-c729281fa2e9","type":"detection","updated_at":"2021-10-14T01:30:22.036Z","updated_by":"elastic","version":1} +{"exported_list_items_count":0} diff --git a/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts b/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts index aa1bd7a5db5cc..a53e37f363d05 100644 --- a/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { getServiceNowConnector } from '../../objects/case'; +import { getServiceNowConnector, getServiceNowITSMHealthResponse } from '../../objects/case'; import { SERVICE_NOW_MAPPING, TOASTER } from '../../screens/configure_cases'; @@ -43,8 +43,16 @@ describe('Cases connectors', () => { id: '123', owner: 'securitySolution', }; + + const snConnector = getServiceNowConnector(); + beforeEach(() => { cleanKibana(); + cy.intercept('GET', `${snConnector.URL}/api/x_elas2_inc_int/elastic_api/health*`, { + statusCode: 200, + body: getServiceNowITSMHealthResponse(), + }); + cy.intercept('POST', '/api/actions/connector').as('createConnector'); cy.intercept('POST', '/api/cases/configure', (req) => { const connector = req.body.connector; @@ -52,6 +60,7 @@ describe('Cases connectors', () => { res.send(200, { ...configureResult, connector }); }); }).as('saveConnector'); + cy.intercept('GET', '/api/cases/configure', (req) => { req.reply((res) => { const resBody = @@ -77,7 +86,7 @@ describe('Cases connectors', () => { loginAndWaitForPageWithoutDateRange(CASES_URL); goToEditExternalConnection(); openAddNewConnectorOption(); - addServiceNowConnector(getServiceNowConnector()); + addServiceNowConnector(snConnector); cy.wait('@createConnector').then(({ response }) => { cy.wrap(response!.statusCode).should('eql', 200); diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts index 8530f949664b8..c8b6f73912acf 100644 --- a/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts @@ -81,7 +81,7 @@ describe('Exceptions Table', () => { cy.wait('@export').then(({ response }) => cy - .wrap(response?.body!) + .wrap(response?.body) .should('eql', expectedExportedExceptionList(this.exceptionListResponse)) ); }); diff --git a/x-pack/plugins/security_solution/cypress/objects/case.ts b/x-pack/plugins/security_solution/cypress/objects/case.ts index af9b34f542046..b0bfdbf16c705 100644 --- a/x-pack/plugins/security_solution/cypress/objects/case.ts +++ b/x-pack/plugins/security_solution/cypress/objects/case.ts @@ -44,6 +44,14 @@ export interface IbmResilientConnectorOptions { incidentTypes: string[]; } +interface ServiceNowHealthResponse { + result: { + name: string; + scope: string; + version: string; + }; +} + export const getCase1 = (): TestCase => ({ name: 'This is the title of the case', tags: ['Tag1', 'Tag2'], @@ -60,6 +68,14 @@ export const getServiceNowConnector = (): Connector => ({ password: 'password', }); +export const getServiceNowITSMHealthResponse = (): ServiceNowHealthResponse => ({ + result: { + name: 'Elastic', + scope: 'x_elas2_inc_int', + version: '1.0.0', + }, +}); + export const getJiraConnectorOptions = (): JiraConnectorOptions => ({ issueType: '10006', priority: 'High', diff --git a/x-pack/plugins/security_solution/cypress/objects/exception.ts b/x-pack/plugins/security_solution/cypress/objects/exception.ts index 81c3b885ab94d..b772924697148 100644 --- a/x-pack/plugins/security_solution/cypress/objects/exception.ts +++ b/x-pack/plugins/security_solution/cypress/objects/exception.ts @@ -41,6 +41,5 @@ export const expectedExportedExceptionList = ( exceptionListResponse: Cypress.Response<ExceptionListItemSchema> ): string => { const jsonrule = exceptionListResponse.body; - - return `"{\\"_version\\":\\"${jsonrule._version}\\",\\"created_at\\":\\"${jsonrule.created_at}\\",\\"created_by\\":\\"elastic\\",\\"description\\":\\"${jsonrule.description}\\",\\"id\\":\\"${jsonrule.id}\\",\\"immutable\\":false,\\"list_id\\":\\"test_exception_list\\",\\"name\\":\\"Test exception list\\",\\"namespace_type\\":\\"single\\",\\"os_types\\":[],\\"tags\\":[],\\"tie_breaker_id\\":\\"${jsonrule.tie_breaker_id}\\",\\"type\\":\\"detection\\",\\"updated_at\\":\\"${jsonrule.updated_at}\\",\\"updated_by\\":\\"elastic\\",\\"version\\":1}\\n"\n""\n{"exception_list_items_details":"{\\"exported_count\\":0}\\n"}\n`; + return `{"_version":"${jsonrule._version}","created_at":"${jsonrule.created_at}","created_by":"elastic","description":"${jsonrule.description}","id":"${jsonrule.id}","immutable":false,"list_id":"test_exception_list","name":"Test exception list","namespace_type":"single","os_types":[],"tags":[],"tie_breaker_id":"${jsonrule.tie_breaker_id}","type":"detection","updated_at":"${jsonrule.updated_at}","updated_by":"elastic","version":1}\n{"exported_list_items_count":0}\n`; }; diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts.ts b/x-pack/plugins/security_solution/cypress/screens/alerts.ts index d18a8e1ba10ab..0a815705f5b21 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts.ts @@ -16,8 +16,6 @@ export const ALERT_CHECKBOX = '[data-test-subj="select-event"].euiCheckbox__inpu export const ALERT_GRID_CELL = '[data-test-subj="dataGridRowCell"]'; -export const ALERT_ID = '[data-test-subj="draggable-content-_id"]'; - export const ALERT_RISK_SCORE_HEADER = '[data-test-subj="dataGridHeaderCell-signal.rule.risk_score"]'; @@ -45,26 +43,17 @@ export const MANAGE_ALERT_DETECTION_RULES_BTN = '[data-test-subj="manage-alert-d export const MARK_ALERT_ACKNOWLEDGED_BTN = '[data-test-subj="acknowledged-alert-status"]'; -export const MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN = - '[data-test-subj="markSelectedAlertsAcknowledgedButton"]'; - export const NUMBER_OF_ALERTS = '[data-test-subj="events-viewer-panel"] [data-test-subj="server-side-event-count"]'; export const OPEN_ALERT_BTN = '[data-test-subj="open-alert-status"]'; -export const OPEN_SELECTED_ALERTS_BTN = '[data-test-subj="openSelectedAlertsButton"]'; - export const OPENED_ALERTS_FILTER_BTN = '[data-test-subj="openAlerts"]'; -export const SELECT_EVENT_CHECKBOX = '[data-test-subj="select-event"]'; - export const SELECTED_ALERTS = '[data-test-subj="selectedShowBulkActionsButton"]'; export const SEND_ALERT_TO_TIMELINE_BTN = '[data-test-subj="send-alert-to-timeline-button"]'; -export const SHOWING_ALERTS = '[data-test-subj="showingAlerts"]'; - export const TAKE_ACTION_POPOVER_BTN = '[data-test-subj="selectedShowBulkActionsButton"]'; export const TIMELINE_CONTEXT_MENU_BTN = '[data-test-subj="timeline-context-menu-button"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts_details.ts b/x-pack/plugins/security_solution/cypress/screens/alerts_details.ts index 2c288aa59374c..c740a669d059a 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts_details.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts_details.ts @@ -24,8 +24,6 @@ export const INVESTIGATION_TIME_ENRICHMENT_SECTION = export const JSON_VIEW_WRAPPER = '[data-test-subj="jsonViewWrapper"]'; -export const JSON_CONTENT = '[data-test-subj="jsonView"]'; - export const JSON_LINES = '.euiCodeBlock__line'; export const JSON_VIEW_TAB = '[data-test-subj="jsonViewTab"]'; @@ -36,16 +34,12 @@ export const TABLE_TAB = '[data-test-subj="tableTab"]'; export const TABLE_ROWS = '.euiTableRow'; -export const THREAT_CONTENT = '[data-test-subj^=draggable-content-]'; - export const THREAT_DETAILS_ACCORDION = '.euiAccordion__triggerWrapper'; export const THREAT_DETAILS_VIEW = '[data-test-subj="threat-details-view-0"]'; export const THREAT_INTEL_TAB = '[data-test-subj="threatIntelTab"]'; -export const THREAT_SUMMARY_VIEW = '[data-test-subj="threat-summary-view"]'; - export const TITLE = '.euiTitle'; export const UPDATE_ENRICHMENT_RANGE_BUTTON = '[data-test-subj="enrichment-button"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts index e4e6a5610fdbe..39e08e29bdc2a 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts @@ -21,14 +21,10 @@ export const DUPLICATE_RULE_ACTION_BTN = '[data-test-subj="duplicateRuleAction"] export const DUPLICATE_RULE_MENU_PANEL_BTN = '[data-test-subj="rules-details-duplicate-rule"]'; -export const REFRESH_BTN = '[data-test-subj="refreshRulesAction"] button'; - export const ACTIVATE_RULE_BULK_BTN = '[data-test-subj="activateRuleBulk"]'; export const DEACTIVATE_RULE_BULK_BTN = '[data-test-subj="deactivateRuleBulk"]'; -export const EXPORT_RULE_BULK_BTN = '[data-test-subj="exportRuleBulk"]'; - export const DELETE_RULE_BULK_BTN = '[data-test-subj="deleteRuleBulk"]'; export const DUPLICATE_RULE_BULK_BTN = '[data-test-subj="duplicateRuleBulk"]'; @@ -37,8 +33,6 @@ export const ELASTIC_RULES_BTN = '[data-test-subj="showElasticRulesFilterButton" export const EXPORT_ACTION_BTN = '[data-test-subj="exportRuleAction"]'; -export const FIFTH_RULE = 4; - export const FIRST_RULE = 0; export const FOURTH_RULE = 3; @@ -72,8 +66,6 @@ export const RULES_ROW = '.euiTableRow'; export const RULES_MONIROTING_TABLE = '[data-test-subj="allRulesTableTab-monitoring"]'; -export const SEVENTH_RULE = 6; - export const SEVERITY = '[data-test-subj="severity"]'; export const SHOWING_RULES_TEXT = '[data-test-subj="showingRules"]'; @@ -92,8 +84,6 @@ export const rowsPerPageSelector = (count: number) => export const pageSelector = (pageNumber: number) => `[data-test-subj="pagination-button-${pageNumber - 1}"]`; -export const NEXT_BTN = '[data-test-subj="pagination-button-next"]'; - export const SELECT_ALL_RULES_BTN = '[data-test-subj="selectAllRules"]'; export const RULES_EMPTY_PROMPT = '[data-test-subj="rulesEmptyPrompt"]'; @@ -103,3 +93,7 @@ export const RULES_DELETE_CONFIRMATION_MODAL = '[data-test-subj="allRulesDeleteC export const MODAL_CONFIRMATION_BTN = '[data-test-subj="confirmModalConfirmButton"]'; export const RULE_DETAILS_DELETE_BTN = '[data-test-subj="rules-details-delete-rule"]'; + +export const ALERT_DETAILS_CELLS = '[data-test-subj="dataGridRowCell"]'; + +export const SERVER_SIDE_EVENT_COUNT = '[data-test-subj="server-side-event-count"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/all_cases.ts b/x-pack/plugins/security_solution/cypress/screens/all_cases.ts index fa6b6add57bac..9d653fb384a1a 100644 --- a/x-pack/plugins/security_solution/cypress/screens/all_cases.ts +++ b/x-pack/plugins/security_solution/cypress/screens/all_cases.ts @@ -5,10 +5,6 @@ * 2.0. */ -export const ALL_CASES_CASE = (id: string) => { - return `[data-test-subj="cases-table-row-${id}"]`; -}; - export const ALL_CASES_CLOSED_CASES_STATS = '[data-test-subj="closedStatsHeader"]'; export const ALL_CASES_COMMENTS_COUNT = '[data-test-subj="case-table-column-commentCount"]'; @@ -19,8 +15,6 @@ export const ALL_CASES_CREATE_NEW_CASE_TABLE_BTN = '[data-test-subj="cases-table export const ALL_CASES_IN_PROGRESS_CASES_STATS = '[data-test-subj="inProgressStatsHeader"]'; -export const ALL_CASES_ITEM_ACTIONS_BTN = '[data-test-subj="euiCollapsedItemActionsButton"]'; - export const ALL_CASES_NAME = '[data-test-subj="case-details-link"]'; export const ALL_CASES_OPEN_CASES_COUNT = '[data-test-subj="case-status-filter"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/case_details.ts b/x-pack/plugins/security_solution/cypress/screens/case_details.ts index ef8f45b222dd0..8ec9a3fdacffc 100644 --- a/x-pack/plugins/security_solution/cypress/screens/case_details.ts +++ b/x-pack/plugins/security_solution/cypress/screens/case_details.ts @@ -5,16 +5,11 @@ * 2.0. */ -export const CASE_ACTIONS_BTN = '[data-test-subj="property-actions-ellipses"]'; - export const CASE_DETAILS_DESCRIPTION = '[data-test-subj="description-action"] [data-test-subj="user-action-markdown"]'; export const CASE_DETAILS_PAGE_TITLE = '[data-test-subj="header-page-title"]'; -export const CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN = - '[data-test-subj="push-to-external-service"]'; - export const CASE_DETAILS_STATUS = '[data-test-subj="case-view-status-dropdown"]'; export const CASE_DETAILS_TAGS = '[data-test-subj="case-tags"]'; @@ -34,10 +29,6 @@ export const CONNECTOR_CARD_DETAILS = '[data-test-subj="connector-card"]'; export const CONNECTOR_TITLE = '[data-test-subj="connector-card"] span.euiTitle'; -export const DELETE_CASE_BTN = '[data-test-subj="property-actions-trash"]'; - -export const DELETE_CASE_CONFIRMATION_BTN = '[data-test-subj="confirmModalConfirmButton"]'; - export const PARTICIPANTS = 1; export const REPORTER = 0; diff --git a/x-pack/plugins/security_solution/cypress/screens/common/callouts.ts b/x-pack/plugins/security_solution/cypress/screens/common/callouts.ts index 032d244f76977..d2dbf6da4aed2 100644 --- a/x-pack/plugins/security_solution/cypress/screens/common/callouts.ts +++ b/x-pack/plugins/security_solution/cypress/screens/common/callouts.ts @@ -5,8 +5,6 @@ * 2.0. */ -export const CALLOUT = '[data-test-subj^="callout-"]'; - export const callOutWithId = (id: string) => `[data-test-subj^="callout-${id}"]`; export const CALLOUT_DISMISS_BTN = '[data-test-subj^="callout-dismiss-"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/configure_cases.ts b/x-pack/plugins/security_solution/cypress/screens/configure_cases.ts index 1ad91ed0977a0..1014835f81efe 100644 --- a/x-pack/plugins/security_solution/cypress/screens/configure_cases.ts +++ b/x-pack/plugins/security_solution/cypress/screens/configure_cases.ts @@ -20,8 +20,6 @@ export const PASSWORD = '[data-test-subj="connector-servicenow-password-form-inp export const SAVE_BTN = '[data-test-subj="saveNewActionButton"]'; -export const SAVE_CHANGES_BTN = '[data-test-subj="case-configure-action-bottom-bar-save-button"]'; - export const SERVICE_NOW_CONNECTOR_CARD = '[data-test-subj=".servicenow-card"]'; export const TOASTER = '[data-test-subj="euiToastHeader"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts index 4748a48dbeb11..3510df6186870 100644 --- a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts @@ -58,8 +58,6 @@ export const COMBO_BOX_CLEAR_BTN = '[data-test-subj="comboBoxClearButton"]'; export const COMBO_BOX_INPUT = '[data-test-subj="comboBoxInput"]'; -export const COMBO_BOX_RESULT = '.euiFilterSelectItem'; - export const CREATE_AND_ACTIVATE_BTN = '[data-test-subj="create-activate"]'; export const CUSTOM_QUERY_INPUT = '[data-test-subj="queryInput"]'; @@ -70,9 +68,6 @@ export const THREAT_MAPPING_COMBO_BOX_INPUT = export const THREAT_MATCH_CUSTOM_QUERY_INPUT = '[data-test-subj="detectionEngineStepDefineRuleQueryBar"] [data-test-subj="queryInput"]'; -export const THREAT_MATCH_INDICATOR_QUERY_INPUT = - '[data-test-subj="detectionEngineStepDefineRuleThreatMatchIndices"] [data-test-subj="queryInput"]'; - export const THREAT_MATCH_QUERY_INPUT = '[data-test-subj="detectionEngineStepDefineThreatRuleQueryBar"] [data-test-subj="queryInput"]'; @@ -206,12 +201,6 @@ export const SCHEDULE_INTERVAL_AMOUNT_INPUT = export const SCHEDULE_INTERVAL_UNITS_INPUT = '[data-test-subj="detectionEngineStepScheduleRuleInterval"] [data-test-subj="timeType"]'; -export const SCHEDULE_LOOKBACK_AMOUNT_INPUT = - '[data-test-subj="detectionEngineStepScheduleRuleFrom"] [data-test-subj="timeType"]'; - -export const SCHEDULE_LOOKBACK_UNITS_INPUT = - '[data-test-subj="detectionEngineStepScheduleRuleFrom"] [data-test-subj="schedule-units-input"]'; - export const SEVERITY_DROPDOWN = '[data-test-subj="detectionEngineStepAboutRuleSeverity"] [data-test-subj="select"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/edit_rule.ts b/x-pack/plugins/security_solution/cypress/screens/edit_rule.ts index 8d8520e109b15..73f3640071251 100644 --- a/x-pack/plugins/security_solution/cypress/screens/edit_rule.ts +++ b/x-pack/plugins/security_solution/cypress/screens/edit_rule.ts @@ -7,5 +7,4 @@ export const EDIT_SUBMIT_BUTTON = '[data-test-subj="ruleEditSubmitButton"]'; export const BACK_TO_RULE_DETAILS = '[data-test-subj="ruleEditBackToRuleDetails"]'; -export const KIBANA_LOADING_INDICATOR = '[data-test-subj="globalLoadingIndicator"]'; export const KIBANA_LOADING_COMPLETE_INDICATOR = '[data-test-subj="globalLoadingIndicator-hidden"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/exceptions.ts b/x-pack/plugins/security_solution/cypress/screens/exceptions.ts index bd6d3b7887206..e5027ee8b4f3a 100644 --- a/x-pack/plugins/security_solution/cypress/screens/exceptions.ts +++ b/x-pack/plugins/security_solution/cypress/screens/exceptions.ts @@ -32,14 +32,10 @@ export const ADD_NESTED_BTN = '[data-test-subj="exceptionsNestedButton"]'; export const ENTRY_DELETE_BTN = '[data-test-subj="builderItemEntryDeleteButton"]'; -export const FIELD_INPUT_LIST_BTN = '[data-test-subj="comboBoxToggleListButton"]'; - export const CANCEL_BTN = '[data-test-subj="cancelExceptionAddButton"]'; export const BUILDER_MODAL_BODY = '[data-test-subj="exceptionsBuilderWrapper"]'; -export const EXCEPTIONS_TABLE_TAB = '[data-test-subj="allRulesTableTab-exceptions"]'; - export const EXCEPTIONS_TABLE = '[data-test-subj="exceptions-table"]'; export const EXCEPTIONS_TABLE_SEARCH = '[data-test-subj="exceptionsHeaderSearchInput"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/fields_browser.ts b/x-pack/plugins/security_solution/cypress/screens/fields_browser.ts index 1115dfb00914e..4a5f813c301db 100644 --- a/x-pack/plugins/security_solution/cypress/screens/fields_browser.ts +++ b/x-pack/plugins/security_solution/cypress/screens/fields_browser.ts @@ -15,14 +15,10 @@ export const FIELDS_BROWSER_CHECKBOX = (id: string) => { export const FIELDS_BROWSER_CONTAINER = '[data-test-subj="fields-browser-container"]'; -export const FIELDS_BROWSER_DRAGGABLE_HOST_GEO_COUNTRY_NAME_HEADER = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="field-name-host.geo.country_name"]`; - export const FIELDS_BROWSER_FIELDS_COUNT = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="fields-count"]`; export const FIELDS_BROWSER_FILTER_INPUT = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="field-search"]`; -export const FIELDS_BROWSER_HEADER_DROP_AREA = '[data-test-subj="headers-group"]'; - export const FIELDS_BROWSER_HOST_CATEGORIES_COUNT = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="host-category-count"]`; export const FIELDS_BROWSER_HOST_GEO_CITY_NAME_CHECKBOX = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="field-host.geo.city_name-checkbox"]`; @@ -35,11 +31,6 @@ export const FIELDS_BROWSER_HOST_GEO_CONTINENT_NAME_CHECKBOX = `${FIELDS_BROWSER export const FIELDS_BROWSER_HEADER_HOST_GEO_CONTINENT_NAME_HEADER = '[data-test-subj="timeline"] [data-test-subj="header-text-host.geo.continent_name"]'; -export const FIELDS_BROWSER_HOST_GEO_COUNTRY_NAME_CHECKBOX = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="field-host.geo.country_name-checkbox"]`; - -export const FIELDS_BROWSER_HOST_GEO_COUNTRY_NAME_HEADER = - '[data-test-subj="timeline"] [data-test-subj="header-text-host.geo.country_name"]'; - export const FIELDS_BROWSER_MESSAGE_CHECKBOX = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="field-message-checkbox"]`; export const FIELDS_BROWSER_MESSAGE_HEADER = @@ -47,8 +38,6 @@ export const FIELDS_BROWSER_MESSAGE_HEADER = export const FIELDS_BROWSER_RESET_FIELDS = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="reset-fields"]`; -export const FIELDS_BROWSER_TITLE = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="field-browser-title"]`; - export const FIELDS_BROWSER_SELECTED_CATEGORY_COUNT = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="selected-category-count-badge"]`; export const FIELDS_BROWSER_SELECTED_CATEGORY_TITLE = `${FIELDS_BROWSER_CONTAINER} [data-test-subj="selected-category-title"]`; diff --git a/x-pack/plugins/security_solution/cypress/screens/hosts/events.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/events.ts index de4acdd721c68..57de63b92a08b 100644 --- a/x-pack/plugins/security_solution/cypress/screens/hosts/events.ts +++ b/x-pack/plugins/security_solution/cypress/screens/hosts/events.ts @@ -5,18 +5,11 @@ * 2.0. */ -export const CLOSE_MODAL = '[data-test-subj="modal-inspect-close"]'; - export const EVENTS_VIEWER_FIELDS_BUTTON = '[data-test-subj="events-viewer-panel"] [data-test-subj="show-field-browser"]'; -export const EVENTS_VIEWER_PANEL = '[data-test-subj="events-viewer-panel"]'; - export const FIELDS_BROWSER_CONTAINER = '[data-test-subj="fields-browser-container"]'; -export const HEADER_SUBTITLE = - '[data-test-subj="events-viewer-panel"] [data-test-subj="header-panel-subtitle"]'; - export const HOST_GEO_CITY_NAME_CHECKBOX = '[data-test-subj="field-host.geo.city_name-checkbox"]'; export const HOST_GEO_CITY_NAME_HEADER = @@ -32,9 +25,6 @@ export const INSPECT_MODAL = '[data-test-subj="modal-inspect-euiModal"]'; export const INSPECT_QUERY = '[data-test-subj="events-viewer-panel"] [data-test-subj="inspect-icon-button"]'; -export const LOAD_MORE = - '[data-test-subj="events-viewer-panel"] [data-test-subj="TimelineMoreButton"'; - export const SERVER_SIDE_EVENT_COUNT = '[data-test-subj="server-side-event-count"]'; export const EVENTS_VIEWER_PAGINATION = diff --git a/x-pack/plugins/security_solution/cypress/screens/hosts/main.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/main.ts index 95381b06f44e9..4f1dd8387c63f 100644 --- a/x-pack/plugins/security_solution/cypress/screens/hosts/main.ts +++ b/x-pack/plugins/security_solution/cypress/screens/hosts/main.ts @@ -13,8 +13,6 @@ export const AUTHENTICATIONS_TAB = '[data-test-subj="navigation-authentications" export const EVENTS_TAB = '[data-test-subj="navigation-events"]'; -export const KQL_SEARCH_BAR = '[data-test-subj="queryInput"]'; - export const UNCOMMON_PROCESSES_TAB = '[data-test-subj="navigation-uncommonProcesses"]'; export const HOST_OVERVIEW = `[data-test-subj="host-overview"]`; diff --git a/x-pack/plugins/security_solution/cypress/screens/rule_details.ts b/x-pack/plugins/security_solution/cypress/screens/rule_details.ts index 9bc22f35741d9..fb1fded1fe8a6 100644 --- a/x-pack/plugins/security_solution/cypress/screens/rule_details.ts +++ b/x-pack/plugins/security_solution/cypress/screens/rule_details.ts @@ -58,8 +58,6 @@ export const FIELDS_BROWSER_BTN = export const REFRESH_BUTTON = '[data-test-subj="refreshButton"]'; -export const RULE_ABOUT_DETAILS_HEADER_TOGGLE = '[data-test-subj="stepAboutDetailsToggle"]'; - export const RULE_NAME_HEADER = '[data-test-subj="header-page-title"]'; export const RULE_NAME_OVERRIDE_DETAILS = 'Rule name override'; @@ -83,8 +81,6 @@ export const RUNS_EVERY_DETAILS = 'Runs every'; export const SCHEDULE_DETAILS = '[data-test-subj=schedule] [data-test-subj="listItemColumnStepRuleDescription"]'; -export const SCHEDULE_STEP = '[data-test-subj="schedule"] .euiDescriptionList__description'; - export const SEVERITY_DETAILS = 'Severity'; export const TAGS_DETAILS = 'Tags'; diff --git a/x-pack/plugins/security_solution/cypress/screens/shared.ts b/x-pack/plugins/security_solution/cypress/screens/shared.ts index 99a0e423c563a..8a7ba48b1415d 100644 --- a/x-pack/plugins/security_solution/cypress/screens/shared.ts +++ b/x-pack/plugins/security_solution/cypress/screens/shared.ts @@ -5,6 +5,4 @@ * 2.0. */ -export const NOTIFICATION_TOASTS = '[data-test-subj="globalToastList"]'; - export const TOAST_ERROR = '.euiToast--danger'; diff --git a/x-pack/plugins/security_solution/cypress/screens/sourcerer.ts b/x-pack/plugins/security_solution/cypress/screens/sourcerer.ts index 142307735d340..874fc7352e908 100644 --- a/x-pack/plugins/security_solution/cypress/screens/sourcerer.ts +++ b/x-pack/plugins/security_solution/cypress/screens/sourcerer.ts @@ -28,4 +28,3 @@ export const SOURCERER_TIMELINE = { radioCustomLabel: '[data-test-subj="timeline-sourcerer-radio"] label.euiRadio__label[for="custom"]', }; -export const SOURCERER_TIMELINE_ADVANCED = '[data-test-subj="advanced-settings"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index 4cf5d2f87f7a9..2e412bbed6fdc 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -26,8 +26,6 @@ export const CASE = (id: string) => { export const CLOSE_TIMELINE_BTN = '[data-test-subj="close-timeline"]'; -export const COLUMN_HEADERS = '[data-test-subj="column-headers"] [data-test-subj^=header-text]'; - export const COMBO_BOX = '.euiComboBoxOption__content'; export const CREATE_NEW_TIMELINE = '[data-test-subj="timeline-new"]'; @@ -41,17 +39,8 @@ export const FAVORITE_TIMELINE = '[data-test-subj="timeline-favorite-filled-star export const FIELD_BROWSER = '[data-test-subj="show-field-browser"]'; -export const GRAPH_TAB_BUTTON = '[data-test-subj="timelineTabs-graph"]'; - -export const HEADER = '[data-test-subj="header"]'; - -export const HEADERS_GROUP = - '[data-test-subj="events-viewer-panel"] [data-test-subj="headers-group"]'; - export const ID_HEADER_FIELD = '[data-test-subj="timeline"] [data-test-subj="header-text-_id"]'; -export const ID_FIELD = '[data-test-subj="timeline"] [data-test-subj="field-name-_id"]'; - export const ID_TOGGLE_FIELD = '[data-test-subj="toggle-field-_id"]'; export const ID_HOVER_ACTION_OVERFLOW_BTN = '[data-test-subj="more-actions-_id"]'; @@ -66,11 +55,6 @@ export const NOTE_CARD_CONTENT = '[data-test-subj="notes"]'; export const EVENT_NOTE = '[data-test-subj="timeline-notes-button-small"]'; -export const NOTE_BY_NOTE_ID = (noteId: string) => - `[data-test-subj="note-preview-${noteId}"] .euiMarkdownFormat`; - -export const NOTE_CONTENT = (noteId: string) => `${NOTE_BY_NOTE_ID(noteId)} p`; - export const NOTES_TEXT_AREA = '[data-test-subj="add-a-note"] textarea'; export const NOTES_TAB_BUTTON = '[data-test-subj="timelineTabs-notes"]'; @@ -96,12 +80,8 @@ export const OPEN_TIMELINE_TEMPLATE_ICON = export const PIN_EVENT = '[data-test-subj="pin"]'; -export const PINNED_TAB_BUTTON = '[data-test-subj="timelineTabs-pinned"]'; - export const PROVIDER_BADGE = '[data-test-subj="providerBadge"]'; -export const REMOVE_COLUMN = '[data-test-subj="remove-column"]'; - export const RESET_FIELDS = '[data-test-subj="fields-browser-container"] [data-test-subj="reset-fields"]'; @@ -112,18 +92,6 @@ export const SEARCH_OR_FILTER_CONTAINER = export const INDICATOR_MATCH_ROW_RENDER = '[data-test-subj="threat-match-row"]'; -export const QUERY_TAB_EVENTS_TABLE = '[data-test-subj="query-events-table"]'; - -export const QUERY_TAB_EVENTS_BODY = '[data-test-subj="query-tab-flyout-body"]'; - -export const QUERY_TAB_EVENTS_FOOTER = '[data-test-subj="query-tab-flyout-footer"]'; - -export const PINNED_TAB_EVENTS_TABLE = '[data-test-subj="pinned-events-table"]'; - -export const PINNED_TAB_EVENTS_BODY = '[data-test-subj="pinned-tab-flyout-body"]'; - -export const PINNED_TAB_EVENTS_FOOTER = '[data-test-subj="pinned-tab-flyout-footer"]'; - export const QUERY_TAB_BUTTON = '[data-test-subj="timelineTabs-query"]'; export const SERVER_SIDE_EVENT_COUNT = '[data-test-subj="server-side-event-count"]'; @@ -145,8 +113,6 @@ export const TIMELINE_CORRELATION_INPUT = '[data-test-subj="eqlQueryBarTextInput export const TIMELINE_CORRELATION_TAB = '[data-test-subj="timelineTabs-eql"]'; -export const TIMELINE_BOTTOM_BAR_CONTAINER = '[data-test-subj="timeline-bottom-bar-container"]'; - export const TIMELINE_DATA_PROVIDERS_ACTION_MENU = '[data-test-subj="providerActions"]'; export const TIMELINE_ADD_FIELD_BUTTON = '[data-test-subj="addField"]'; @@ -213,8 +179,6 @@ export const TIMELINE_SETTINGS_ICON = '[data-test-subj="settings-plus-in-circle" export const TIMELINE_SEARCH_OR_FILTER = '[data-test-subj="timeline-select-search-or-filter"]'; -export const TIMELINE_SEARCH_OR_FILTER_CONTENT = '.searchOrFilterPopover'; - export const TIMELINE_KQLMODE_SEARCH = '[data-test-subj="kqlModePopoverSearch"]'; export const TIMELINE_KQLMODE_FILTER = '[data-test-subj="kqlModePopoverFilter"]'; @@ -257,10 +221,6 @@ export const TIMELINE_TABS = '[data-test-subj="timeline"] .euiTabs'; export const TIMELINE_TAB_CONTENT_EQL = '[data-test-subj="timeline-tab-content-eql"]'; -export const TIMELINE_TAB_CONTENT_QUERY = '[data-test-subj="timeline-tab-content-query"]'; - -export const TIMELINE_TAB_CONTENT_PINNED = '[data-test-subj="timeline-tab-content-pinned"]'; - export const TIMELINE_TAB_CONTENT_GRAPHS_NOTES = '[data-test-subj="timeline-tab-content-graph-notes"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/timelines.ts b/x-pack/plugins/security_solution/cypress/screens/timelines.ts index ab6c790c599ab..ca60250330f83 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timelines.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timelines.ts @@ -27,6 +27,4 @@ export const TIMELINES_PINNED_EVENT_COUNT = '[data-test-subj="pinned-event-count export const TIMELINES_TABLE = '[data-test-subj="timelines-table"]'; -export const TIMELINES_USERNAME = '[data-test-subj="username"]'; - export const REFRESH_BUTTON = '[data-test-subj="refreshButton-linkIcon"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts index 5b8ad49f61b0d..067c9957189b9 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts @@ -17,13 +17,11 @@ import { LOADING_ALERTS_PANEL, MANAGE_ALERT_DETECTION_RULES_BTN, MARK_ALERT_ACKNOWLEDGED_BTN, - MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN, OPEN_ALERT_BTN, OPENED_ALERTS_FILTER_BTN, SEND_ALERT_TO_TIMELINE_BTN, TAKE_ACTION_POPOVER_BTN, TIMELINE_CONTEXT_MENU_BTN, - SELECT_EVENT_CHECKBOX, } from '../screens/alerts'; import { LOADING_INDICATOR, REFRESH_BUTTON } from '../screens/security_header'; import { TIMELINE_COLUMN_SPINNER } from '../screens/timeline'; @@ -73,10 +71,6 @@ export const expandFirstAlert = () => { export const viewThreatIntelTab = () => cy.get(THREAT_INTEL_TAB).click(); -export const viewThreatDetails = () => { - cy.get(EXPAND_ALERT_BTN).first().click({ force: true }); -}; - export const setEnrichmentDates = (from?: string, to?: string) => { cy.get(ENRICHMENT_QUERY_RANGE_PICKER).within(() => { if (from) { @@ -130,11 +124,6 @@ export const markAcknowledgedFirstAlert = () => { cy.get(MARK_ALERT_ACKNOWLEDGED_BTN).click(); }; -export const markAcknowledgedAlerts = () => { - cy.get(TAKE_ACTION_POPOVER_BTN).click({ force: true }); - cy.get(MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN).click(); -}; - export const selectNumberOfAlerts = (numberOfAlerts: number) => { for (let i = 0; i < numberOfAlerts; i++) { cy.get(ALERT_CHECKBOX).eq(i).click({ force: true }); @@ -174,8 +163,3 @@ export const waitForAlertsPanelToBeLoaded = () => { cy.get(LOADING_ALERTS_PANEL).should('exist'); cy.get(LOADING_ALERTS_PANEL).should('not.exist'); }; - -export const waitForAlertsToBeLoaded = () => { - const expectedNumberOfDisplayedAlerts = 25; - cy.get(SELECT_EVENT_CHECKBOX).should('have.length', expectedNumberOfDisplayedAlerts); -}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts index 6b985c7009b27..84b81108f8be3 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts @@ -27,7 +27,6 @@ import { SORT_RULES_BTN, EXPORT_ACTION_BTN, EDIT_RULE_ACTION_BTN, - NEXT_BTN, RULE_AUTO_REFRESH_IDLE_MODAL, RULE_AUTO_REFRESH_IDLE_MODAL_CONTINUE, rowsPerPageSelector, @@ -41,10 +40,9 @@ import { RULES_DELETE_CONFIRMATION_MODAL, ACTIVATE_RULE_BULK_BTN, DEACTIVATE_RULE_BULK_BTN, - EXPORT_RULE_BULK_BTN, RULE_DETAILS_DELETE_BTN, } from '../screens/alerts_detection_rules'; -import { ALL_ACTIONS, DELETE_RULE } from '../screens/rule_details'; +import { ALL_ACTIONS } from '../screens/rule_details'; import { LOADING_INDICATOR } from '../screens/security_header'; export const activateRule = (rulePosition: number) => { @@ -97,11 +95,6 @@ export const deleteFirstRule = () => { cy.get(DELETE_RULE_ACTION_BTN).click(); }; -export const deleteRule = () => { - cy.get(ALL_ACTIONS).click(); - cy.get(DELETE_RULE).click(); -}; - export const deleteSelectedRules = () => { cy.get(BULK_ACTIONS_BTN).click({ force: true }); cy.get(DELETE_RULE_BULK_BTN).click(); @@ -137,11 +130,6 @@ export const deactivateSelectedRules = () => { cy.get(DEACTIVATE_RULE_BULK_BTN).click(); }; -export const exportSelectedRules = () => { - cy.get(BULK_ACTIONS_BTN).click({ force: true }); - cy.get(EXPORT_RULE_BULK_BTN).click(); -}; - export const exportFirstRule = () => { cy.get(COLLAPSED_ACTION_BTN).first().click({ force: true }); cy.get(EXPORT_ACTION_BTN).click(); @@ -214,11 +202,6 @@ export const waitForRulesTableToBeRefreshed = () => { cy.get(RULES_TABLE_REFRESH_INDICATOR).should('not.exist'); }; -export const waitForRulesTableToBeAutoRefreshed = () => { - cy.get(RULES_TABLE_AUTOREFRESH_INDICATOR).should('exist'); - cy.get(RULES_TABLE_AUTOREFRESH_INDICATOR).should('not.exist'); -}; - export const waitForPrebuiltDetectionRulesToBeLoaded = () => { cy.get(LOAD_PREBUILT_RULES_BTN).should('not.exist'); cy.get(RULES_TABLE).should('exist'); @@ -273,9 +256,3 @@ export const goToPage = (pageNumber: number) => { cy.get(pageSelector(pageNumber)).last().click({ force: true }); waitForRulesTableToBeRefreshed(); }; - -export const goToNextPage = () => { - cy.get(RULES_TABLE_REFRESH_INDICATOR).should('not.exist'); - cy.get(NEXT_BTN).click({ force: true }); - waitForRulesTableToBeRefreshed(); -}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/case_details.ts b/x-pack/plugins/security_solution/cypress/tasks/case_details.ts index f64c3c9d79007..57f6f24ee890a 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/case_details.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/case_details.ts @@ -6,18 +6,7 @@ */ import { TIMELINE_TITLE } from '../screens/timeline'; -import { - CASE_ACTIONS_BTN, - CASE_DETAILS_TIMELINE_LINK_MARKDOWN, - DELETE_CASE_BTN, - DELETE_CASE_CONFIRMATION_BTN, -} from '../screens/case_details'; - -export const deleteCase = () => { - cy.get(CASE_ACTIONS_BTN).first().click(); - cy.get(DELETE_CASE_BTN).click(); - cy.get(DELETE_CASE_CONFIRMATION_BTN).click(); -}; +import { CASE_DETAILS_TIMELINE_LINK_MARKDOWN } from '../screens/case_details'; export const openCaseTimeline = () => { cy.get(CASE_DETAILS_TIMELINE_LINK_MARKDOWN).click(); diff --git a/x-pack/plugins/security_solution/cypress/tasks/common.ts b/x-pack/plugins/security_solution/cypress/tasks/common.ts index d726d5daa5cbc..d247b787576b0 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common.ts @@ -7,6 +7,7 @@ import { esArchiverResetKibana } from './es_archiver'; import { RuleEcs } from '../../common/ecs/rule'; +import { LOADING_INDICATOR } from '../screens/security_header'; const primaryButton = 0; @@ -155,3 +156,8 @@ export const deleteCases = () => { }; export const scrollToBottom = () => cy.scrollTo('bottom'); + +export const waitForPageToBeLoaded = () => { + cy.get(LOADING_INDICATOR).should('exist'); + cy.get(LOADING_INDICATOR).should('not.exist'); +}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts index b7fb0785736f6..591be21b5682b 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts @@ -32,7 +32,6 @@ import { CUSTOM_QUERY_REQUIRED, DEFAULT_RISK_SCORE_INPUT, DEFINE_CONTINUE_BUTTON, - DEFINE_EDIT_TAB, EQL_QUERY_INPUT, EQL_QUERY_PREVIEW_HISTOGRAM, EQL_QUERY_VALIDATION_SPINNER, @@ -495,10 +494,6 @@ export const fillDefineMachineLearningRuleAndContinue = (rule: MachineLearningRu cy.get(MACHINE_LEARNING_DROPDOWN_INPUT).should('not.exist'); }; -export const goToDefineStepTab = () => { - cy.get(DEFINE_EDIT_TAB).click({ force: true }); -}; - export const goToAboutStepTab = () => { cy.get(ABOUT_EDIT_TAB).click({ force: true }); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts b/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts index 97e93ef8194a4..4548c921890c8 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts @@ -5,11 +5,9 @@ * 2.0. */ -import { Exception } from '../objects/exception'; import { FIELD_INPUT, OPERATOR_INPUT, - VALUES_INPUT, CANCEL_BTN, BUILDER_MODAL_BODY, EXCEPTION_ITEM_CONTAINER, @@ -38,25 +36,6 @@ export const addExceptionEntryOperatorValue = (operator: string, index = 0) => { cy.get(BUILDER_MODAL_BODY).click(); }; -export const addExceptionEntryValue = (values: string[], index = 0) => { - values.forEach((value) => { - cy.get(VALUES_INPUT).eq(index).type(`${value}{enter}`); - }); - cy.get(BUILDER_MODAL_BODY).click(); -}; - -export const addExceptionEntry = (exception: Exception, index = 0) => { - addExceptionEntryFieldValue(exception.field, index); - addExceptionEntryOperatorValue(exception.operator, index); - addExceptionEntryValue(exception.values, index); -}; - -export const addNestedExceptionEntry = (exception: Exception, index = 0) => { - addExceptionEntryFieldValue(exception.field, index); - addExceptionEntryOperatorValue(exception.operator, index); - addExceptionEntryValue(exception.values, index); -}; - export const closeExceptionBuilderModal = () => { cy.get(CANCEL_BTN).click(); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/exceptions_table.ts b/x-pack/plugins/security_solution/cypress/tasks/exceptions_table.ts index 838af066abd60..f2bc0c1f7e6ed 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/exceptions_table.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/exceptions_table.ts @@ -6,7 +6,6 @@ */ import { - EXCEPTIONS_TABLE_TAB, EXCEPTIONS_TABLE, EXCEPTIONS_TABLE_SEARCH, EXCEPTIONS_TABLE_DELETE_BTN, @@ -16,10 +15,6 @@ import { EXCEPTIONS_TABLE_EXPORT_BTN, } from '../screens/exceptions'; -export const goToExceptionsTable = () => { - cy.get(EXCEPTIONS_TABLE_TAB).should('exist').click({ force: true }); -}; - export const waitForExceptionsTableToBeLoaded = () => { cy.get(EXCEPTIONS_TABLE).should('exist'); cy.get(EXCEPTIONS_TABLE_SEARCH).should('exist'); diff --git a/x-pack/plugins/security_solution/cypress/tasks/fields_browser.ts b/x-pack/plugins/security_solution/cypress/tasks/fields_browser.ts index 72945f557ac1b..ee8bdb3b023dd 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/fields_browser.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/fields_browser.ts @@ -5,12 +5,8 @@ * 2.0. */ -import { drag, drop } from '../tasks/common'; - import { FIELDS_BROWSER_FILTER_INPUT, - FIELDS_BROWSER_DRAGGABLE_HOST_GEO_COUNTRY_NAME_HEADER, - FIELDS_BROWSER_HEADER_DROP_AREA, FIELDS_BROWSER_HOST_GEO_CITY_NAME_CHECKBOX, FIELDS_BROWSER_HOST_GEO_CONTINENT_NAME_CHECKBOX, FIELDS_BROWSER_MESSAGE_CHECKBOX, @@ -37,15 +33,6 @@ export const addsHostGeoContinentNameToTimeline = () => { }); }; -export const addsHostGeoCountryNameToTimelineDraggingIt = () => { - cy.get(FIELDS_BROWSER_DRAGGABLE_HOST_GEO_COUNTRY_NAME_HEADER).should('exist'); - cy.get(FIELDS_BROWSER_DRAGGABLE_HOST_GEO_COUNTRY_NAME_HEADER).then((field) => drag(field)); - - cy.get(FIELDS_BROWSER_HEADER_DROP_AREA) - .first() - .then((headersDropArea) => drop(headersDropArea)); -}; - export const clearFieldsBrowser = () => { cy.get(FIELDS_BROWSER_FILTER_INPUT).type('{selectall}{backspace}'); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts index d40b43bac1e3f..bf8abe4328b96 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts @@ -7,14 +7,12 @@ import { drag, drop } from '../common'; import { - CLOSE_MODAL, EVENTS_VIEWER_FIELDS_BUTTON, EVENTS_VIEWER_PAGINATION, FIELDS_BROWSER_CONTAINER, HOST_GEO_CITY_NAME_CHECKBOX, HOST_GEO_COUNTRY_NAME_CHECKBOX, INSPECT_QUERY, - LOAD_MORE, SERVER_SIDE_EVENT_COUNT, } from '../../screens/hosts/events'; import { DATAGRID_HEADERS } from '../../screens/timeline'; @@ -32,19 +30,9 @@ export const addsHostGeoCountryNameToHeader = () => { }); }; -export const closeModal = () => { - cy.get(CLOSE_MODAL).click(); -}; - -export const loadMoreEvents = () => { - cy.get(LOAD_MORE).click({ force: true }); -}; - export const openEventsViewerFieldsBrowser = () => { cy.get(EVENTS_VIEWER_FIELDS_BUTTON).click({ force: true }); - cy.get(SERVER_SIDE_EVENT_COUNT).should('not.have.text', '0'); - cy.get(FIELDS_BROWSER_CONTAINER).should('exist'); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/security_header.ts b/x-pack/plugins/security_solution/cypress/tasks/security_header.ts index 0d6ab9449da86..558b750e2641b 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/security_header.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/security_header.ts @@ -22,7 +22,3 @@ export const navigateFromHeaderTo = (page: string) => { export const refreshPage = () => { cy.get(REFRESH_BUTTON).click({ force: true }).should('not.have.text', 'Updating'); }; - -export const waitForThePageToBeUpdated = () => { - cy.get(REFRESH_BUTTON).should('not.have.text', 'Updating'); -}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/security_main.ts b/x-pack/plugins/security_solution/cypress/tasks/security_main.ts index 01651b7b943d0..9b8af6c5ceef6 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/security_main.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/security_main.ts @@ -7,7 +7,6 @@ import { CLOSE_TIMELINE_BUTTON, - MAIN_PAGE, TIMELINE_TOGGLE_BUTTON, TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON, } from '../screens/security_main'; @@ -25,13 +24,6 @@ export const closeTimelineUsingCloseButton = () => { cy.get(CLOSE_TIMELINE_BUTTON).filter(':visible').click(); }; -export const openTimelineIfClosed = () => - cy.get(MAIN_PAGE).then(($page) => { - if ($page.find(TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON).length === 1) { - openTimelineUsingToggle(); - } - }); - export const enterFullScreenMode = () => { cy.get(TIMELINE_FULL_SCREEN_BUTTON).first().click({ force: true }); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts index 039e8ed44886e..4c6b73de80940 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts @@ -22,7 +22,6 @@ import { COMBO_BOX, CREATE_NEW_TIMELINE, FIELD_BROWSER, - ID_FIELD, ID_HEADER_FIELD, ID_TOGGLE_FIELD, ID_HOVER_ACTION_OVERFLOW_BTN, @@ -69,8 +68,6 @@ import { } from '../screens/timeline'; import { REFRESH_BUTTON, TIMELINE } from '../screens/timelines'; -import { drag, drop } from '../tasks/common'; - import { closeFieldsBrowser, filterFieldsBrowser } from '../tasks/fields_browser'; export const hostExistsQuery = 'host.name: *'; @@ -121,10 +118,6 @@ export const goToCorrelationTab = () => { return cy.root().find(TIMELINE_CORRELATION_TAB); }; -export const getNotePreviewByNoteId = (noteId: string) => { - return cy.get(`[data-test-subj="note-preview-${noteId}"]`); -}; - export const goToQueryTab = () => { cy.root() .pipe(($el) => { @@ -302,10 +295,6 @@ export const populateTimeline = () => { cy.get(SERVER_SIDE_EVENT_COUNT).should('not.have.text', '0'); }; -export const unpinFirstEvent = () => { - cy.get(PIN_EVENT).first().click({ force: true }); -}; - const clickTimestampHoverActionOverflowButton = () => { cy.get(TIMESTAMP_HOVER_ACTION_OVERFLOW_BTN).should('exist'); @@ -320,16 +309,6 @@ export const clickTimestampToggleField = () => { cy.get(TIMESTAMP_TOGGLE_FIELD).click({ force: true }); }; -export const dragAndDropIdToggleFieldToTimeline = () => { - cy.get(ID_HEADER_FIELD).should('not.exist'); - - cy.get(ID_FIELD).then((field) => drag(field)); - - cy.get(`[data-test-subj="timeline"] [data-test-subj="headers-group"]`) - .first() - .then((headersDropArea) => drop(headersDropArea)); -}; - export const removeColumn = (columnName: string) => { cy.get(FIELD_BROWSER).first().click(); filterFieldsBrowser(columnName); @@ -350,10 +329,6 @@ export const waitForTimelineChanges = () => { cy.get(TIMELINE_CHANGES_IN_PROGRESS).should('not.exist'); }; -export const waitForEventsPanelToBeLoaded = () => { - cy.get(QUERY_TAB_BUTTON).find('.euiBadge').should('exist'); -}; - /** * We keep clicking on the refresh button until we have the timeline we are looking * for. NOTE: That because refresh happens so fast, the click handler in most cases diff --git a/x-pack/plugins/security_solution/cypress/tsconfig.json b/x-pack/plugins/security_solution/cypress/tsconfig.json index 4efb4c5c56296..a779c3f48d346 100644 --- a/x-pack/plugins/security_solution/cypress/tsconfig.json +++ b/x-pack/plugins/security_solution/cypress/tsconfig.json @@ -8,15 +8,14 @@ "target/**/*" ], "compilerOptions": { - "target": "es5", - "lib": ["es5", "dom"], + "target": "ES2019", "outDir": "target/types", "types": [ "cypress", "cypress-pipe", - "node" + "node", + "resize-observer-polyfill", ], - "resolveJsonModule": true, }, "references": [ { "path": "../tsconfig.json" } diff --git a/x-pack/plugins/security_solution/cypress/upgrade_integration/custom_query_rule.spec.ts b/x-pack/plugins/security_solution/cypress/upgrade_integration/custom_query_rule.spec.ts index 2718c0735a671..1af7a3f9bed03 100644 --- a/x-pack/plugins/security_solution/cypress/upgrade_integration/custom_query_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/upgrade_integration/custom_query_rule.spec.ts @@ -5,25 +5,138 @@ * 2.0. */ -import { RULE_NAME } from '../screens/alerts_detection_rules'; - +import { ALERT_DETAILS_CELLS, SERVER_SIDE_EVENT_COUNT } from '../screens/alerts_detection_rules'; import { - goToManageAlertsDetectionRules, - waitForAlertsIndexToBeCreated, - waitForAlertsPanelToBeLoaded, -} from '../tasks/alerts'; -import { waitForRulesTableToBeLoaded } from '../tasks/alerts_detection_rules'; -import { loginAndWaitForPageWithoutDateRange } from '../tasks/login'; - -import { ALERTS_URL } from '../urls/navigation'; - -describe('After an upgrade, the cusom query rule', () => { - it('Displays the rule', function () { - loginAndWaitForPageWithoutDateRange(ALERTS_URL); - waitForAlertsPanelToBeLoaded(); - waitForAlertsIndexToBeCreated(); - goToManageAlertsDetectionRules(); + ADDITIONAL_LOOK_BACK_DETAILS, + ABOUT_DETAILS, + ABOUT_RULE_DESCRIPTION, + CUSTOM_QUERY_DETAILS, + DEFINITION_DETAILS, + getDetails, + INDEX_PATTERNS_DETAILS, + RISK_SCORE_DETAILS, + RULE_NAME_HEADER, + RULE_TYPE_DETAILS, + RUNS_EVERY_DETAILS, + SCHEDULE_DETAILS, + SEVERITY_DETAILS, + TIMELINE_TEMPLATE_DETAILS, +} from '../screens/rule_details'; + +import { waitForPageToBeLoaded } from '../tasks/common'; +import { waitForRulesTableToBeLoaded, goToRuleDetails } from '../tasks/alerts_detection_rules'; +import { loginAndWaitForPage } from '../tasks/login'; + +import { DETECTIONS_RULE_MANAGEMENT_URL } from '../urls/navigation'; + +const EXPECTED_NUMBER_OF_ALERTS = '1'; + +const alert = { + rule: 'Custom query rule for upgrade', + severity: 'low', + riskScore: '7', + reason: + 'file event with process test, file The file to test, by Security Solution on security-solution.local created low alert Custom query rule for upgrade.', + hostName: 'security-solution.local', + username: 'test', + processName: 'The file to test', + fileName: 'The file to test', + sourceIp: '127.0.0.1', + destinationIp: '127.0.0.2', +}; + +const rule = { + customQuery: '*:*', + name: 'Custom query rule for upgrade', + description: 'My description', + index: ['auditbeat-*'], + severity: 'Low', + riskScore: '7', + timelineTemplate: 'none', + runsEvery: '10s', + lookBack: '179999990s', + timeline: 'None', +}; + +describe('After an upgrade, the custom query rule', () => { + before(() => { + loginAndWaitForPage(DETECTIONS_RULE_MANAGEMENT_URL); waitForRulesTableToBeLoaded(); - cy.get(RULE_NAME).should('have.text', 'Custom query rule for upgrade'); + goToRuleDetails(); + waitForPageToBeLoaded(); + }); + + it('Has the expected alerts number', () => { + cy.get(SERVER_SIDE_EVENT_COUNT).contains(EXPECTED_NUMBER_OF_ALERTS); + }); + + it('Displays the rule details', () => { + cy.get(RULE_NAME_HEADER).should('contain', `${rule.name}`); + cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description); + cy.get(ABOUT_DETAILS).within(() => { + getDetails(SEVERITY_DETAILS).should('have.text', rule.severity); + getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore); + }); + cy.get(DEFINITION_DETAILS).within(() => { + getDetails(INDEX_PATTERNS_DETAILS).should('have.text', rule.index.join('')); + getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery); + getDetails(RULE_TYPE_DETAILS).should('have.text', 'Query'); + getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', rule.timeline); + }); + cy.get(SCHEDULE_DETAILS).within(() => { + getDetails(RUNS_EVERY_DETAILS).should('have.text', rule.runsEvery); + getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should('have.text', rule.lookBack); + }); + }); + + it('Displays the alert details', () => { + cy.get(ALERT_DETAILS_CELLS).first().focus(); + cy.get(ALERT_DETAILS_CELLS).first().type('{rightarrow}'); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.rule) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.severity) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.riskScore) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.reason) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.hostName) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.username) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.processName) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.fileName) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS) + .contains(alert.sourceIp) + .then(($el) => { + cy.wrap($el).type('{rightarrow}'); + }); + cy.get(ALERT_DETAILS_CELLS).contains(alert.destinationIp); }); }); diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index 6aa45a02419ba..371ac66004f48 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -11,6 +11,7 @@ "cypress:open": "yarn cypress open --config-file ./cypress/cypress.json", "cypress:open:ccs": "yarn cypress:open --config integrationFolder=./cypress/ccs_integration", "cypress:open-as-ci": "node ../../../scripts/functional_tests --config ../../test/security_solution_cypress/visual_config.ts", + "cypress:open:upgrade": "yarn cypress:open --config integrationFolder=./cypress/upgrade_integration", "cypress:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/integration/**/*.spec.ts'; status=$?; yarn junit:merge && exit $status", "cypress:run:firefox": "yarn cypress:run:reporter --browser firefox --spec './cypress/integration/**/*.spec.ts'; status=$?; yarn junit:merge && exit $status", "cypress:run:reporter": "yarn cypress run --config-file ./cypress/cypress.json --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json", diff --git a/x-pack/plugins/security_solution/public/common/components/conditions_table/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/conditions_table/__snapshots__/index.test.tsx.snap index 3d37aea431df3..c14e0bb283de0 100644 --- a/x-pack/plugins/security_solution/public/common/components/conditions_table/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/conditions_table/__snapshots__/index.test.tsx.snap @@ -58,7 +58,12 @@ exports[`conditions_table ConditionsTable should render multi item table with an }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> @@ -124,7 +129,12 @@ exports[`conditions_table ConditionsTable should render multi item table with or }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> @@ -165,7 +175,12 @@ exports[`conditions_table ConditionsTable should render single item table correc }, ] } - noItemsMessage="No items found" + noItemsMessage={ + <EuiI18n + default="No items found" + token="euiBasicTable.noItemsMessage" + /> + } responsive={true} tableLayout="fixed" /> diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/alert_summary_view.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/alert_summary_view.test.tsx.snap index 2904d8184261e..d367c68586be1 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/alert_summary_view.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/alert_summary_view.test.tsx.snap @@ -210,7 +210,7 @@ exports[`AlertSummaryView Behavior event code renders additional summary rows 1` class="eventFieldsTable__fieldValue" > <span - class="euiToolTipAnchor" + class="euiToolTipAnchor eui-textTruncate eui-alignMiddle" > Nov 25, 2020 @ 15:42:39.417 </span> @@ -872,7 +872,7 @@ exports[`AlertSummaryView Memory event code renders additional summary rows 1`] class="eventFieldsTable__fieldValue" > <span - class="euiToolTipAnchor" + class="euiToolTipAnchor eui-textTruncate eui-alignMiddle" > Nov 25, 2020 @ 15:42:39.417 </span> diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts b/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts index 76ca5dfe53f4e..23acd90183af4 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts +++ b/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts @@ -25,7 +25,7 @@ import { } from '../../../../timelines/components/timeline/body/renderers/constants'; import { BYTES_FORMAT } from '../../../../timelines/components/timeline/body/renderers/bytes'; import { EVENT_DURATION_FIELD_NAME } from '../../../../timelines/components/duration'; -import { PORT_NAMES } from '../../../../network/components/port'; +import { PORT_NAMES } from '../../../../network/components/port/helpers'; import { INDICATOR_REFERENCE } from '../../../../../common/cti/constants'; import { BrowserField } from '../../../containers/source'; import { DataProvider, IS_OPERATOR } from '../../../../../common/types'; diff --git a/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx index f6df6e132ebee..e525003660a85 100644 --- a/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx @@ -92,23 +92,27 @@ PreferenceFormattedP1DTDate.displayName = 'PreferenceFormattedP1DTDate'; * - a long representation of the date that includes the day of the week (e.g. Thursday, March 21, 2019 6:47pm) * - the raw date value (e.g. 2019-03-22T00:47:46Z) */ -export const FormattedDate = React.memo<{ + +interface FormattedDateProps { + className?: string; fieldName: string; value?: string | number | null; - className?: string; -}>(({ value, fieldName, className = '' }): JSX.Element => { - if (value == null) { - return getOrEmptyTagFromValue(value); +} +export const FormattedDate = React.memo<FormattedDateProps>( + ({ value, fieldName, className = '' }): JSX.Element => { + if (value == null) { + return getOrEmptyTagFromValue(value); + } + const maybeDate = getMaybeDate(value); + return maybeDate.isValid() ? ( + <LocalizedDateTooltip date={maybeDate.toDate()} fieldName={fieldName} className={className}> + <PreferenceFormattedDate value={maybeDate.toDate()} /> + </LocalizedDateTooltip> + ) : ( + getOrEmptyTagFromValue(value) + ); } - const maybeDate = getMaybeDate(value); - return maybeDate.isValid() ? ( - <LocalizedDateTooltip date={maybeDate.toDate()} fieldName={fieldName} className={className}> - <PreferenceFormattedDate value={maybeDate.toDate()} /> - </LocalizedDateTooltip> - ) : ( - getOrEmptyTagFromValue(value) - ); -}); +); FormattedDate.displayName = 'FormattedDate'; diff --git a/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap index d3d20c7183570..fe589b1e253a9 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap @@ -6,23 +6,25 @@ exports[`HeaderSection it renders 1`] = ` > <EuiFlexGroup alignItems="center" + gutterSize="none" > <EuiFlexItem grow={true} > <EuiFlexGroup alignItems="center" + gutterSize="none" responsive={false} > <EuiFlexItem> <EuiTitle size="m" > - <h2 + <h4 data-test-subj="header-section-title" > Test title - </h2> + </h4> </EuiTitle> <Subtitle data-test-subj="header-section-subtitle" diff --git a/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx index f733331bcd691..21a3c4dc614cc 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx @@ -68,12 +68,12 @@ const HeaderSectionComponent: React.FC<HeaderSectionProps> = ({ hideSubtitle = false, }) => ( <Header data-test-subj="header-section" border={border} height={height}> - <EuiFlexGroup alignItems="center"> + <EuiFlexGroup alignItems="center" gutterSize="none"> <EuiFlexItem grow={growLeftSplit}> - <EuiFlexGroup alignItems="center" responsive={false}> + <EuiFlexGroup alignItems="center" responsive={false} gutterSize="none"> <EuiFlexItem> <EuiTitle size={titleSize}> - <h2 data-test-subj="header-section-title"> + <h4 data-test-subj="header-section-title"> {title} {tooltip && ( <> @@ -81,7 +81,7 @@ const HeaderSectionComponent: React.FC<HeaderSectionProps> = ({ <EuiIconTip color="subdued" content={tooltip} size="l" type="iInCircle" /> </> )} - </h2> + </h4> </EuiTitle> {!hideSubtitle && ( diff --git a/x-pack/plugins/security_solution/public/common/components/hover_actions/actions/show_top_n.tsx b/x-pack/plugins/security_solution/public/common/components/hover_actions/actions/show_top_n.tsx index e1546c5220e22..738103f02dcdf 100644 --- a/x-pack/plugins/security_solution/public/common/components/hover_actions/actions/show_top_n.tsx +++ b/x-pack/plugins/security_solution/public/common/components/hover_actions/actions/show_top_n.tsx @@ -30,33 +30,49 @@ const SHOW_TOP = (fieldName: string) => }); interface Props { + className?: string; /** When `Component` is used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality. * When `Component` is used with `EuiContextMenu`, we pass EuiContextMenuItem to render the right style. */ Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon | typeof EuiContextMenuItem; enablePopOver?: boolean; field: string; + flush?: 'left' | 'right' | 'both'; globalFilters?: Filter[]; + iconSide?: 'left' | 'right'; + iconType?: string; + isExpandable?: boolean; onClick: () => void; onFilterAdded?: () => void; ownFocus: boolean; + paddingSize?: 's' | 'm' | 'l' | 'none'; showTooltip?: boolean; showTopN: boolean; + showLegend?: boolean; timelineId?: string | null; + title?: string; value?: string[] | string | null; } export const ShowTopNButton: React.FC<Props> = React.memo( ({ + className, Component, enablePopOver, field, + flush, + iconSide, + iconType, + isExpandable, onClick, onFilterAdded, ownFocus, + paddingSize, + showLegend, showTooltip = true, showTopN, timelineId, + title, value, globalFilters, }) => { @@ -70,31 +86,36 @@ export const ShowTopNButton: React.FC<Props> = React.memo( ? SourcererScopeName.detections : SourcererScopeName.default; const { browserFields, indexPattern } = useSourcererScope(activeScope); - + const icon = iconType ?? 'visBarVertical'; + const side = iconSide ?? 'left'; + const buttonTitle = title ?? SHOW_TOP(field); const basicButton = useMemo( () => Component ? ( <Component - aria-label={SHOW_TOP(field)} + aria-label={buttonTitle} + className={className} data-test-subj="show-top-field" - icon="visBarVertical" - iconType="visBarVertical" + icon={icon} + iconType={icon} + iconSide={side} + flush={flush} onClick={onClick} - title={SHOW_TOP(field)} + title={buttonTitle} > - {SHOW_TOP(field)} + {buttonTitle} </Component> ) : ( <EuiButtonIcon - aria-label={SHOW_TOP(field)} + aria-label={buttonTitle} className="securitySolution__hoverActionButton" data-test-subj="show-top-field" iconSize="s" - iconType="visBarVertical" + iconType={icon} onClick={onClick} /> ), - [Component, field, onClick] + [Component, buttonTitle, className, flush, icon, onClick, side] ); const button = useMemo( @@ -107,7 +128,7 @@ export const ShowTopNButton: React.FC<Props> = React.memo( field, value, })} - content={SHOW_TOP(field)} + content={buttonTitle} shortcut={SHOW_TOP_N_KEYBOARD_SHORTCUT} showShortcut={ownFocus} /> @@ -118,7 +139,7 @@ export const ShowTopNButton: React.FC<Props> = React.memo( ) : ( basicButton ), - [basicButton, field, ownFocus, showTooltip, showTopN, value] + [basicButton, buttonTitle, field, ownFocus, showTooltip, showTopN, value] ); const topNPannel = useMemo( @@ -128,15 +149,37 @@ export const ShowTopNButton: React.FC<Props> = React.memo( field={field} indexPattern={indexPattern} onFilterAdded={onFilterAdded} + paddingSize={paddingSize} + showLegend={showLegend} timelineId={timelineId ?? undefined} toggleTopN={onClick} value={value} globalFilters={globalFilters} /> ), - [browserFields, field, indexPattern, onClick, onFilterAdded, timelineId, value, globalFilters] + [ + browserFields, + field, + indexPattern, + onFilterAdded, + paddingSize, + showLegend, + timelineId, + onClick, + value, + globalFilters, + ] ); + if (isExpandable) { + return ( + <> + {basicButton} + {showTopN && topNPannel} + </> + ); + } + return showTopN ? ( enablePopOver ? ( <EuiPopover diff --git a/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx new file mode 100644 index 0000000000000..0504a17904a75 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { SyntheticEvent } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiButtonIcon, + EuiButtonProps, + EuiLink, + EuiLinkProps, + PropsForAnchor, + PropsForButton, +} from '@elastic/eui'; +import styled from 'styled-components'; + +export const LinkButton: React.FC<PropsForButton<EuiButtonProps> | PropsForAnchor<EuiButtonProps>> = + ({ children, ...props }) => <EuiButton {...props}>{children}</EuiButton>; + +export const LinkAnchor: React.FC<EuiLinkProps> = ({ children, ...props }) => ( + <EuiLink {...props}>{children}</EuiLink> +); + +export const Comma = styled('span')` + margin-right: 5px; + margin-left: 5px; + &::after { + content: ' ,'; + } +`; + +Comma.displayName = 'Comma'; + +const GenericLinkButtonComponent: React.FC<{ + children?: React.ReactNode; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; + dataTestSubj?: string; + href: string; + onClick?: (e: SyntheticEvent) => void; + title?: string; + iconType?: string; +}> = ({ children, Component, dataTestSubj, href, onClick, title, iconType = 'expand' }) => { + return Component ? ( + <Component + data-test-subj={dataTestSubj} + href={href} + iconType={iconType} + onClick={onClick} + title={title} + > + {title ?? children} + </Component> + ) : ( + <LinkButton data-test-subj={dataTestSubj} href={href} onClick={onClick}> + {title ?? children} + </LinkButton> + ); +}; + +export const GenericLinkButton = React.memo(GenericLinkButtonComponent); + +export const PortContainer = styled.div` + & svg { + position: relative; + top: -1px; + } +`; diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.tsx index 7db6b0204b649..c74791b8b3aa7 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/index.tsx @@ -6,19 +6,15 @@ */ import { - EuiButton, - EuiButtonProps, - EuiLink, - EuiLinkProps, - EuiToolTip, + EuiButtonEmpty, + EuiButtonIcon, EuiFlexGroup, EuiFlexItem, - PropsForAnchor, - PropsForButton, + EuiLink, + EuiToolTip, } from '@elastic/eui'; import React, { useMemo, useCallback, SyntheticEvent } from 'react'; import { isNil } from 'lodash/fp'; -import styled from 'styled-components'; import { IP_REPUTATION_LINKS_SETTING, APP_ID } from '../../../../common/constants'; import { @@ -43,22 +39,11 @@ import { isUrlInvalid } from '../../utils/validators'; import * as i18n from './translations'; import { SecurityPageName } from '../../../app/types'; import { getUebaDetailsUrl } from '../link_to/redirect_to_ueba'; +import { LinkButton, LinkAnchor, GenericLinkButton, PortContainer, Comma } from './helpers'; -export const DEFAULT_NUMBER_OF_LINK = 5; - -export const LinkButton: React.FC<PropsForButton<EuiButtonProps> | PropsForAnchor<EuiButtonProps>> = - ({ children, ...props }) => <EuiButton {...props}>{children}</EuiButton>; +export { LinkButton, LinkAnchor } from './helpers'; -export const LinkAnchor: React.FC<EuiLinkProps> = ({ children, ...props }) => ( - <EuiLink {...props}>{children}</EuiLink> -); - -export const PortContainer = styled.div` - & svg { - position: relative; - top: -1px; - } -`; +export const DEFAULT_NUMBER_OF_LINK = 5; // Internal Links const UebaDetailsLinkComponent: React.FC<{ @@ -102,10 +87,13 @@ export const UebaDetailsLink = React.memo(UebaDetailsLinkComponent); const HostDetailsLinkComponent: React.FC<{ children?: React.ReactNode; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; hostName: string; isButton?: boolean; onClick?: (e: SyntheticEvent) => void; -}> = ({ children, hostName, isButton, onClick }) => { + title?: string; +}> = ({ children, Component, hostName, isButton, onClick, title }) => { const { formatUrl, search } = useFormatUrl(SecurityPageName.hosts); const { navigateToApp } = useKibana().services.application; const goToHostDetails = useCallback( @@ -118,19 +106,25 @@ const HostDetailsLinkComponent: React.FC<{ }, [hostName, navigateToApp, search] ); - + const href = useMemo( + () => formatUrl(getHostDetailsUrl(encodeURIComponent(hostName))), + [formatUrl, hostName] + ); return isButton ? ( - <LinkButton + <GenericLinkButton + Component={Component} + dataTestSubj="data-grid-host-details" + href={href} + iconType="expand" onClick={onClick ?? goToHostDetails} - href={formatUrl(getHostDetailsUrl(encodeURIComponent(hostName)))} - data-test-subj="host-details-button" + title={title ?? hostName} > - {children ? children : hostName} - </LinkButton> + {children} + </GenericLinkButton> ) : ( <LinkAnchor onClick={onClick ?? goToHostDetails} - href={formatUrl(getHostDetailsUrl(encodeURIComponent(hostName)))} + href={href} data-test-subj="host-details-button" > {children ? children : hostName} @@ -176,11 +170,14 @@ ExternalLink.displayName = 'ExternalLink'; const NetworkDetailsLinkComponent: React.FC<{ children?: React.ReactNode; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; ip: string; flowTarget?: FlowTarget | FlowTargetSourceDest; isButton?: boolean; onClick?: (e: SyntheticEvent) => void | undefined; -}> = ({ children, ip, flowTarget = FlowTarget.source, isButton, onClick }) => { + title?: string; +}> = ({ Component, children, ip, flowTarget = FlowTarget.source, isButton, onClick, title }) => { const { formatUrl, search } = useFormatUrl(SecurityPageName.network); const { navigateToApp } = useKibana().services.application; const goToNetworkDetails = useCallback( @@ -193,19 +190,25 @@ const NetworkDetailsLinkComponent: React.FC<{ }, [flowTarget, ip, navigateToApp, search] ); + const href = useMemo( + () => formatUrl(getNetworkDetailsUrl(encodeURIComponent(encodeIpv6(ip)))), + [formatUrl, ip] + ); return isButton ? ( - <LinkButton - href={formatUrl(getNetworkDetailsUrl(encodeURIComponent(encodeIpv6(ip))))} + <GenericLinkButton + Component={Component} + dataTestSubj="data-grid-network-details" onClick={onClick ?? goToNetworkDetails} - data-test-subj="network-details" + href={href} + title={title ?? ip} > - {children ? children : ip} - </LinkButton> + {children} + </GenericLinkButton> ) : ( <LinkAnchor onClick={onClick ?? goToNetworkDetails} - href={formatUrl(getNetworkDetailsUrl(encodeURIComponent(encodeIpv6(ip))))} + href={href} data-test-subj="network-details" > {children ? children : ip} @@ -272,63 +275,84 @@ CreateCaseLink.displayName = 'CreateCaseLink'; // External Links export const GoogleLink = React.memo<{ children?: React.ReactNode; link: string }>( - ({ children, link }) => ( - <ExternalLink url={`https://www.google.com/search?q=${encodeURIComponent(link)}`}> - {children ? children : link} - </ExternalLink> - ) + ({ children, link }) => { + const url = useMemo( + () => `https://www.google.com/search?q=${encodeURIComponent(link)}`, + [link] + ); + return <ExternalLink url={url}>{children ? children : link}</ExternalLink>; + } ); GoogleLink.displayName = 'GoogleLink'; export const PortOrServiceNameLink = React.memo<{ children?: React.ReactNode; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; portOrServiceName: number | string; -}>(({ children, portOrServiceName }) => ( - <PortContainer> - <EuiLink - data-test-subj="port-or-service-name-link" - href={`https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=${encodeURIComponent( + onClick?: (e: SyntheticEvent) => void | undefined; + title?: string; +}>(({ Component, title, children, portOrServiceName }) => { + const href = useMemo( + () => + `https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=${encodeURIComponent( String(portOrServiceName) - )}`} - target="_blank" + )}`, + [portOrServiceName] + ); + return Component ? ( + <Component + href={href} + data-test-subj="data-grid-port-or-service-name-link" + title={title} + iconType="link" > - {children ? children : portOrServiceName} - </EuiLink> - </PortContainer> -)); + {title ?? children ?? portOrServiceName} + </Component> + ) : ( + <PortContainer> + <EuiLink data-test-subj="port-or-service-name-link" href={href} target="_blank"> + {children ? children : portOrServiceName} + </EuiLink> + </PortContainer> + ); +}); PortOrServiceNameLink.displayName = 'PortOrServiceNameLink'; export const Ja3FingerprintLink = React.memo<{ children?: React.ReactNode; ja3Fingerprint: string; -}>(({ children, ja3Fingerprint }) => ( - <EuiLink - data-test-subj="ja3-fingerprint-link" - href={`https://sslbl.abuse.ch/ja3-fingerprints/${encodeURIComponent(ja3Fingerprint)}`} - target="_blank" - > - {children ? children : ja3Fingerprint} - </EuiLink> -)); +}>(({ children, ja3Fingerprint }) => { + const href = useMemo( + () => `https://sslbl.abuse.ch/ja3-fingerprints/${encodeURIComponent(ja3Fingerprint)}`, + [ja3Fingerprint] + ); + return ( + <EuiLink data-test-subj="ja3-fingerprint-link" href={href} target="_blank"> + {children ? children : ja3Fingerprint} + </EuiLink> + ); +}); Ja3FingerprintLink.displayName = 'Ja3FingerprintLink'; export const CertificateFingerprintLink = React.memo<{ children?: React.ReactNode; certificateFingerprint: string; -}>(({ children, certificateFingerprint }) => ( - <EuiLink - data-test-subj="certificate-fingerprint-link" - href={`https://sslbl.abuse.ch/ssl-certificates/sha1/${encodeURIComponent( - certificateFingerprint - )}`} - target="_blank" - > - {children ? children : certificateFingerprint} - </EuiLink> -)); +}>(({ children, certificateFingerprint }) => { + const href = useMemo( + () => + `https://sslbl.abuse.ch/ssl-certificates/sha1/${encodeURIComponent(certificateFingerprint)}`, + [certificateFingerprint] + ); + return ( + <EuiLink data-test-subj="certificate-fingerprint-link" href={href} target="_blank"> + {children ? children : certificateFingerprint} + </EuiLink> + ); +}); CertificateFingerprintLink.displayName = 'CertificateFingerprintLink'; @@ -354,16 +378,6 @@ const isReputationLink = ( (rowItem as ReputationLinkSetting).url_template !== undefined && (rowItem as ReputationLinkSetting).name !== undefined; -export const Comma = styled('span')` - margin-right: 5px; - margin-left: 5px; - &::after { - content: ' ,'; - } -`; - -Comma.displayName = 'Comma'; - const defaultNameMapping: Record<DefaultReputationLink, string> = { [DefaultReputationLink['virustotal.com']]: i18n.VIEW_VIRUS_TOTAL, [DefaultReputationLink['talosIntelligence.com']]: i18n.VIEW_TALOS_INTELLIGENCE, @@ -463,11 +477,13 @@ ReputationLinkComponent.displayName = 'ReputationLinkComponent'; export const ReputationLink = React.memo(ReputationLinkComponent); export const WhoIsLink = React.memo<{ children?: React.ReactNode; domain: string }>( - ({ children, domain }) => ( - <ExternalLink url={`https://www.iana.org/whois?q=${encodeURIComponent(domain)}`}> - {children ? children : domain} - </ExternalLink> - ) + ({ children, domain }) => { + const url = useMemo( + () => `https://www.iana.org/whois?q=${encodeURIComponent(domain)}`, + [domain] + ); + return <ExternalLink url={url}>{children ? children : domain}</ExternalLink>; + } ); WhoIsLink.displayName = 'WhoIsLink'; diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx index f25e8311ff8fe..7eac477741a5c 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx @@ -79,6 +79,7 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> = legendPosition, mapping, onError, + paddingSize = 'm', panelHeight = DEFAULT_PANEL_HEIGHT, setAbsoluteRangeDatePickerTarget = 'global', setQuery, @@ -200,7 +201,11 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> = return ( <> <InspectButtonContainer show={!isInitialLoading}> - <HistogramPanel data-test-subj={`${id}Panel`} height={panelHeight}> + <HistogramPanel + data-test-subj={`${id}Panel`} + height={panelHeight} + paddingSize={paddingSize} + > {loading && !isInitialLoading && ( <EuiProgress data-test-subj="initialLoadingPanelMatrixOverTime" diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts index 7cb4144e1acba..b67505a66be44 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts @@ -52,6 +52,7 @@ interface MatrixHistogramBasicProps { legendPosition?: Position; mapping?: MatrixHistogramMappingTypes; panelHeight?: number; + paddingSize?: 's' | 'm' | 'l' | 'none'; setQuery: GlobalTimeArgs['setQuery']; startDate: GlobalTimeArgs['from']; stackByOptions: MatrixHistogramOption[]; diff --git a/x-pack/plugins/security_solution/public/common/components/page/index.tsx b/x-pack/plugins/security_solution/public/common/components/page/index.tsx index fca49bd4539ec..9666a0837b046 100644 --- a/x-pack/plugins/security_solution/public/common/components/page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page/index.tsx @@ -31,13 +31,58 @@ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimar z-index: 9950 !important; } + .euiDataGridRowCell__expandButton .euiDataGridRowCell__actionButtonIcon { + display: none; + + &:first-child, + &:nth-child(2), + &:nth-child(3) { + display: inline-flex; + } + + } + /* overrides the default styling of EuiDataGrid expand popover footer to make it a column of actions instead of the default actions row */ - .euiDataGridRowCell__popover .euiPopoverFooter .euiFlexGroup { - flex-direction: column; - align-items: flex-start; + + .euiDataGridRowCell__popover { + + max-width: 815px !important; + max-height: none !important; + overflow: hidden; + + + .expandable-top-value-button { + &.euiButtonEmpty--primary:enabled:focus, + .euiButtonEmpty--primary:focus { + background-color: transparent; + } + } + + + &.euiPopover__panel.euiPopover__panel-isOpen { + padding: 8px 0; + min-width: 65px; + } + + + .euiPopoverFooter { + border: 0; + .euiFlexGroup { + flex-direction: column; + + .euiButtonEmpty .euiButtonContent { + justify-content: left; + } + + .euiFlexItem:first-child, + .euiFlexItem:nth-child(2) { + display: none; + } + } + } } /* @@ -54,10 +99,14 @@ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimar } /* hide open draggable popovers when a modal is being displayed to prevent them from covering the modal */ - body.euiBody-hasOverlayMask .withHoverActions__popover.euiPopover__panel-isOpen{ - visibility: hidden !important; + body.euiBody-hasOverlayMask { + .euiDataGridRowCell__popover.euiPopover__panel-isOpen, + .withHoverActions__popover.euiPopover__panel-isOpen { + visibility: hidden !important; + } } + /* ensure elastic charts tooltips appear above open euiPopovers */ .echTooltip { z-index: 9950; diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx index 1556f2d0f3d13..1eef44d587ed0 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx @@ -81,6 +81,8 @@ export interface OwnProps { timelineId?: string; toggleTopN: () => void; onFilterAdded?: () => void; + paddingSize?: 's' | 'm' | 'l' | 'none'; + showLegend?: boolean; value?: string[] | string | null; globalFilters?: Filter[]; } @@ -101,6 +103,8 @@ const StatefulTopNComponent: React.FC<Props> = ({ globalQuery = EMPTY_QUERY, kqlMode, onFilterAdded, + paddingSize, + showLegend, timelineId, toggleTopN, value, @@ -160,7 +164,9 @@ const StatefulTopNComponent: React.FC<Props> = ({ from={timelineId === TimelineId.active ? activeTimelineFrom : from} indexPattern={indexPattern} options={options} + paddingSize={paddingSize} query={timelineId === TimelineId.active ? EMPTY_QUERY : globalQuery} + showLegend={showLegend} setAbsoluteRangeDatePickerTarget={timelineId === TimelineId.active ? 'timeline' : 'global'} setQuery={setQuery} timelineId={timelineId} diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx index 7335d6203697f..f40ee8670171c 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx @@ -55,8 +55,10 @@ export interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery filters: Filter[]; indexPattern: IIndexPattern; options: TopNOption[]; + paddingSize?: 's' | 'm' | 'l' | 'none'; query: Query; setAbsoluteRangeDatePickerTarget: InputsModelId; + showLegend?: boolean; timelineId?: string; toggleTopN: () => void; onFilterAdded?: () => void; @@ -72,7 +74,9 @@ const TopNComponent: React.FC<Props> = ({ from, indexPattern, options, + paddingSize, query, + showLegend, setAbsoluteRangeDatePickerTarget, setQuery, timelineId, @@ -127,7 +131,9 @@ const TopNComponent: React.FC<Props> = ({ indexPattern={indexPattern} indexNames={view === 'raw' ? rawIndices : allIndices} onlyField={field} + paddingSize={paddingSize} query={query} + showLegend={showLegend} setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget} setQuery={setQuery} showSpacer={false} @@ -141,7 +147,9 @@ const TopNComponent: React.FC<Props> = ({ filters={filters} headerChildren={headerChildren} onlyField={field} + paddingSize={paddingSize} query={query} + showLegend={showLegend} setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget} timelineId={timelineId} /> diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts index 8a678be0616b9..ba806da195461 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts @@ -6,7 +6,8 @@ */ import { navTabs } from '../../../app/home/home_navigations'; -import { getTitle } from './helpers'; +import { getTitle, isQueryStateEmpty } from './helpers'; +import { CONSTANTS } from './constants'; describe('Helpers Url_State', () => { describe('getTitle', () => { @@ -31,4 +32,58 @@ describe('Helpers Url_State', () => { expect(result).toEqual(''); }); }); + + describe('isQueryStateEmpty', () => { + test('returns true if queryState is undefined', () => { + const result = isQueryStateEmpty(undefined, CONSTANTS.savedQuery); + expect(result).toBeTruthy(); + }); + + test('returns true if queryState is null', () => { + const result = isQueryStateEmpty(null, CONSTANTS.savedQuery); + expect(result).toBeTruthy(); + }); + + test('returns true if url key is "query" and queryState is empty string', () => { + const result = isQueryStateEmpty({}, CONSTANTS.appQuery); + expect(result).toBeTruthy(); + }); + + test('returns false if url key is "query" and queryState is not empty', () => { + const result = isQueryStateEmpty( + { query: { query: '*:*' }, language: 'kuery' }, + CONSTANTS.appQuery + ); + expect(result).toBeFalsy(); + }); + + test('returns true if url key is "filters" and queryState is empty', () => { + const result = isQueryStateEmpty([], CONSTANTS.filters); + expect(result).toBeTruthy(); + }); + + test('returns false if url key is "filters" and queryState is not empty', () => { + const result = isQueryStateEmpty( + [{ query: { query: '*:*' }, meta: { key: '123' } }], + CONSTANTS.filters + ); + expect(result).toBeFalsy(); + }); + + // TODO: Is this a bug, or intended? + test('returns false if url key is "timeline" and queryState is empty', () => { + const result = isQueryStateEmpty({}, CONSTANTS.timeline); + expect(result).toBeFalsy(); + }); + + test('returns true if url key is "timeline" and queryState id is empty string', () => { + const result = isQueryStateEmpty({ id: '', isOpen: true }, CONSTANTS.timeline); + expect(result).toBeTruthy(); + }); + + test('returns false if url key is "timeline" and queryState is not empty', () => { + const result = isQueryStateEmpty({ id: '123', isOpen: true }, CONSTANTS.timeline); + expect(result).toBeFalsy(); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts index ba09ed914dc68..5b6bb0400ccdf 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts @@ -199,8 +199,11 @@ export const updateTimerangeUrl = ( return timeRange; }; -export const isQueryStateEmpty = (queryState: ValueUrlState | null, urlKey: KeyUrlState) => - queryState === null || +export const isQueryStateEmpty = ( + queryState: ValueUrlState | undefined | null, + urlKey: KeyUrlState +): boolean => + queryState == null || (urlKey === CONSTANTS.appQuery && isEmpty((queryState as Query).query)) || (urlKey === CONSTANTS.filters && isEmpty(queryState)) || (urlKey === CONSTANTS.timeline && (queryState as TimelineUrl).id === ''); diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/__mocks__/use_endpoint_privileges.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/__mocks__/use_endpoint_privileges.ts index 80cf11fecd847..80ca534534187 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/__mocks__/use_endpoint_privileges.ts +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/__mocks__/use_endpoint_privileges.ts @@ -12,6 +12,7 @@ export const useEndpointPrivileges = jest.fn(() => { loading: false, canAccessFleet: true, canAccessEndpointManagement: true, + isPlatinumPlus: true, }; return endpointPrivilegesMock; }); diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx b/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx index 028473f5c2001..437d27278102b 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx @@ -24,7 +24,12 @@ export interface UserPrivilegesState { export const initialUserPrivilegesState = (): UserPrivilegesState => ({ listPrivileges: { loading: false, error: undefined, result: undefined }, detectionEnginePrivileges: { loading: false, error: undefined, result: undefined }, - endpointPrivileges: { loading: true, canAccessEndpointManagement: false, canAccessFleet: false }, + endpointPrivileges: { + loading: true, + canAccessEndpointManagement: false, + canAccessFleet: false, + isPlatinumPlus: false, + }, kibanaSecuritySolutionsPrivileges: { crud: false, read: false }, }); diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.test.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.test.ts index a05d1ac8d3588..82443e913499b 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.test.ts @@ -5,15 +5,27 @@ * 2.0. */ -import { renderHook, RenderHookResult, RenderResult } from '@testing-library/react-hooks'; +import { act, renderHook, RenderHookResult, RenderResult } from '@testing-library/react-hooks'; import { useHttp, useCurrentUser } from '../../lib/kibana'; import { EndpointPrivileges, useEndpointPrivileges } from './use_endpoint_privileges'; import { securityMock } from '../../../../../security/public/mocks'; import { appRoutesService } from '../../../../../fleet/common'; import { AuthenticatedUser } from '../../../../../security/common'; +import { licenseService } from '../../hooks/use_license'; import { fleetGetCheckPermissionsHttpMock } from '../../../management/pages/mocks'; jest.mock('../../lib/kibana'); +jest.mock('../../hooks/use_license', () => { + const licenseServiceInstance = { + isPlatinumPlus: jest.fn(), + }; + return { + licenseService: licenseServiceInstance, + useLicense: () => { + return licenseServiceInstance; + }, + }; +}); describe('When using useEndpointPrivileges hook', () => { let authenticatedUser: AuthenticatedUser; @@ -33,6 +45,7 @@ describe('When using useEndpointPrivileges hook', () => { fleetApiMock = fleetGetCheckPermissionsHttpMock( useHttp() as Parameters<typeof fleetGetCheckPermissionsHttpMock>[0] ); + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); render = () => { const hookRenderResponse = renderHook(() => useEndpointPrivileges()); @@ -60,6 +73,7 @@ describe('When using useEndpointPrivileges hook', () => { canAccessEndpointManagement: false, canAccessFleet: false, loading: true, + isPlatinumPlus: true, }); // Make user service available @@ -69,15 +83,19 @@ describe('When using useEndpointPrivileges hook', () => { canAccessEndpointManagement: false, canAccessFleet: false, loading: true, + isPlatinumPlus: true, }); // Release the API response - releaseApiResponse!(); - await fleetApiMock.waitForApi(); + await act(async () => { + fleetApiMock.waitForApi(); + releaseApiResponse!(); + }); expect(result.current).toEqual({ canAccessEndpointManagement: true, canAccessFleet: true, loading: false, + isPlatinumPlus: true, }); }); @@ -99,6 +117,7 @@ describe('When using useEndpointPrivileges hook', () => { canAccessEndpointManagement: false, canAccessFleet: true, // this is only true here because I did not adjust the API mock loading: false, + isPlatinumPlus: true, }); }); @@ -115,6 +134,7 @@ describe('When using useEndpointPrivileges hook', () => { canAccessEndpointManagement: false, canAccessFleet: false, loading: false, + isPlatinumPlus: true, }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.ts index b8db0c5c0fbc9..315935104d107 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.ts +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/use_endpoint_privileges.ts @@ -8,6 +8,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { useCurrentUser, useHttp } from '../../lib/kibana'; import { appRoutesService, CheckPermissionsResponse } from '../../../../../fleet/common'; +import { useLicense } from '../../hooks/use_license'; export interface EndpointPrivileges { loading: boolean; @@ -15,6 +16,7 @@ export interface EndpointPrivileges { canAccessFleet: boolean; /** If user has permissions to access Endpoint management (includes check to ensure they also have access to fleet) */ canAccessEndpointManagement: boolean; + isPlatinumPlus: boolean; } /** @@ -27,6 +29,7 @@ export const useEndpointPrivileges = (): EndpointPrivileges => { const http = useHttp(); const user = useCurrentUser(); const isMounted = useRef<boolean>(true); + const license = useLicense(); const [canAccessFleet, setCanAccessFleet] = useState<boolean>(false); const [fleetCheckDone, setFleetCheckDone] = useState<boolean>(false); @@ -62,8 +65,9 @@ export const useEndpointPrivileges = (): EndpointPrivileges => { loading: !fleetCheckDone || !user, canAccessFleet, canAccessEndpointManagement: canAccessFleet && isSuperUser, + isPlatinumPlus: license.isPlatinumPlus(), }; - }, [canAccessFleet, fleetCheckDone, isSuperUser, user]); + }, [canAccessFleet, fleetCheckDone, isSuperUser, user, license]); // Capture if component is unmounted useEffect( diff --git a/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.test.tsx b/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.test.tsx new file mode 100644 index 0000000000000..a4e6f0a66dfc9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.test.tsx @@ -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 { EuiDataGridColumn } from '@elastic/eui'; +import type { + BrowserFields, + TimelineNonEcsData, +} from '../../../../../timelines/common/search_strategy'; +import { TGridCellAction } from '../../../../../timelines/common/types'; +import { Ecs } from '../../../../common/ecs'; +import { ColumnHeaderType } from '../../../timelines/store/timeline/model'; + +import { defaultCellActions, EmptyComponent } from './default_cell_actions'; +import { COLUMNS_WITH_LINKS } from './helpers'; + +describe('default cell actions', () => { + const browserFields: BrowserFields = {}; + const data: TimelineNonEcsData[][] = [[]]; + const ecsData: Ecs[] = []; + const timelineId = 'mockTimelineId'; + const pageSize = 10; + + test('columns without any link action (e.g.: signal.status) should return an empty component (not null or data grid would crash)', () => { + const columnHeaders = [ + { + category: 'signal', + columnHeaderType: 'no-filtered' as ColumnHeaderType, + id: 'signal.status', + type: 'string', + aggregatable: true, + initialWidth: 105, + }, + ]; + + const columnsWithCellActions: EuiDataGridColumn[] = columnHeaders.map((header) => { + const buildAction = (tGridCellAction: TGridCellAction) => + tGridCellAction({ + browserFields, + data, + ecsData, + header: columnHeaders.find((h) => h.id === header.id), + pageSize, + timelineId, + }); + + return { + ...header, + cellActions: defaultCellActions?.map(buildAction), + }; + }); + + expect(columnsWithCellActions[0]?.cellActions?.length).toEqual(5); + expect(columnsWithCellActions[0]?.cellActions![4]).toEqual(EmptyComponent); + }); + + const columnHeadersToTest = COLUMNS_WITH_LINKS.map((c) => [ + { + category: 'signal', + columnHeaderType: 'no-filtered' as ColumnHeaderType, + id: c.columnId, + type: c.fieldType, + aggregatable: true, + initialWidth: 105, + }, + ]); + describe.each(columnHeadersToTest)('columns with a link action', (columnHeaders) => { + test(`${columnHeaders.id ?? columnHeaders.type}`, () => { + const columnsWithCellActions: EuiDataGridColumn[] = [columnHeaders].map((header) => { + const buildAction = (tGridCellAction: TGridCellAction) => + tGridCellAction({ + browserFields, + data, + ecsData, + header: [columnHeaders].find((h) => h.id === header.id), + pageSize, + timelineId, + }); + + return { + ...header, + cellActions: defaultCellActions?.map(buildAction), + }; + }); + + expect(columnsWithCellActions[0]?.cellActions?.length).toEqual(5); + expect(columnsWithCellActions[0]?.cellActions![4]).not.toEqual(EmptyComponent); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.tsx b/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.tsx index 149a0c62b8b6a..012b84e06ed82 100644 --- a/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.tsx +++ b/x-pack/plugins/security_solution/public/common/lib/cell_actions/default_cell_actions.tsx @@ -5,21 +5,28 @@ * 2.0. */ -import React, { useCallback, useState, useMemo } from 'react'; -import { Filter } from '../../../../../../../src/plugins/data/public'; +import { EuiDataGridColumnCellActionProps } from '@elastic/eui'; +import { head, getOr, get, isEmpty } from 'lodash/fp'; +import React, { useMemo } from 'react'; import type { BrowserFields, TimelineNonEcsData, } from '../../../../../timelines/common/search_strategy'; -import { DataProvider, TGridCellAction } from '../../../../../timelines/common/types'; +import { + ColumnHeaderOptions, + DataProvider, + TGridCellAction, +} from '../../../../../timelines/common/types'; import { getPageRowIndex } from '../../../../../timelines/public'; +import { Ecs } from '../../../../common/ecs'; import { getMappedNonEcsValue } from '../../../timelines/components/timeline/body/data_driven_columns'; +import { FormattedFieldValue } from '../../../timelines/components/timeline/body/renderers/formatted_field'; +import { parseValue } from '../../../timelines/components/timeline/body/renderers/parse_value'; import { IS_OPERATOR } from '../../../timelines/components/timeline/data_providers/data_provider'; -import { allowTopN, escapeDataProviderId } from '../../components/drag_and_drop/helpers'; -import { ShowTopNButton } from '../../components/hover_actions/actions/show_top_n'; -import { getAllFieldsByName } from '../../containers/source'; +import { escapeDataProviderId } from '../../components/drag_and_drop/helpers'; import { useKibana } from '../kibana'; +import { getLink } from './helpers'; /** a noop required by the filter in / out buttons */ const onFilterAdded = () => {}; @@ -36,15 +43,77 @@ const useKibanaServices = () => { return { timelines, filterManager }; }; -/** the default actions shown in `EuiDataGrid` cells */ -export const defaultCellActions: TGridCellAction[] = [ +export const EmptyComponent = () => <></>; + +const cellActionLink = [ + ({ + browserFields, + data, + ecsData, + header, + timelineId, + pageSize, + }: { + browserFields: BrowserFields; + data: TimelineNonEcsData[][]; + ecsData: Ecs[]; + header?: ColumnHeaderOptions; + timelineId: string; + pageSize: number; + }) => + getLink(header?.id, header?.type, header?.linkField) + ? ({ rowIndex, columnId, Component, closePopover }: EuiDataGridColumnCellActionProps) => { + const pageRowIndex = getPageRowIndex(rowIndex, pageSize); + const ecs = pageRowIndex < ecsData.length ? ecsData[pageRowIndex] : null; + const linkValues = header && getOr([], header.linkField ?? '', ecs); + const eventId = header && get('_id' ?? '', ecs); + + if (pageRowIndex >= data.length) { + // data grid expects each cell action always return an element, it crashes if returns null + return <></>; + } + + const values = getMappedNonEcsValue({ + data: data[pageRowIndex], + fieldName: columnId, + }); + + const link = getLink(columnId, header?.type, header?.linkField); + const value = parseValue(head(values)); + + return link && eventId && values && !isEmpty(value) ? ( + <FormattedFieldValue + Component={Component} + contextId={`expanded-value-${columnId}-row-${pageRowIndex}-${timelineId}`} + eventId={eventId} + fieldFormat={header?.format || ''} + fieldName={columnId} + fieldType={header?.type || ''} + isButton={true} + isDraggable={false} + value={value} + truncate={false} + title={values.length > 1 ? `${link?.label}: ${value}` : link?.label} + linkValue={head(linkValues)} + onClick={closePopover} + /> + ) : ( + // data grid expects each cell action always return an element, it crashes if returns null + <></> + ); + } + : EmptyComponent, +]; + +export const cellActions: TGridCellAction[] = [ ({ data, pageSize }: { data: TimelineNonEcsData[][]; pageSize: number }) => - ({ rowIndex, columnId, Component }) => { + ({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) => { const { timelines, filterManager } = useKibanaServices(); const pageRowIndex = getPageRowIndex(rowIndex, pageSize); if (pageRowIndex >= data.length) { - return null; + // data grid expects each cell action always return an element, it crashes if returns null + return <></>; } const value = getMappedNonEcsValue({ @@ -72,7 +141,8 @@ export const defaultCellActions: TGridCellAction[] = [ const pageRowIndex = getPageRowIndex(rowIndex, pageSize); if (pageRowIndex >= data.length) { - return null; + // data grid expects each cell action always return an element, it crashes if returns null + return <></>; } const value = getMappedNonEcsValue({ @@ -100,34 +170,8 @@ export const defaultCellActions: TGridCellAction[] = [ const pageRowIndex = getPageRowIndex(rowIndex, pageSize); if (pageRowIndex >= data.length) { - return null; - } - - const value = getMappedNonEcsValue({ - data: data[pageRowIndex], - fieldName: columnId, - }); - - return ( - <> - {timelines.getHoverActions().getCopyButton({ - Component, - field: columnId, - isHoverAction: false, - ownFocus: false, - showTooltip: false, - value, - })} - </> - ); - }, - ({ data, pageSize }: { data: TimelineNonEcsData[][]; pageSize: number }) => - ({ rowIndex, columnId, Component }) => { - const { timelines } = useKibanaServices(); - - const pageRowIndex = getPageRowIndex(rowIndex, pageSize); - if (pageRowIndex >= data.length) { - return null; + // data grid expects each cell action always return an element, it crashes if returns null + return <></>; } const value = getMappedNonEcsValue({ @@ -165,26 +209,14 @@ export const defaultCellActions: TGridCellAction[] = [ </> ); }, - ({ - browserFields, - data, - globalFilters, - timelineId, - pageSize, - }: { - browserFields: BrowserFields; - data: TimelineNonEcsData[][]; - globalFilters?: Filter[]; - timelineId: string; - pageSize: number; - }) => + ({ data, pageSize }: { data: TimelineNonEcsData[][]; pageSize: number }) => ({ rowIndex, columnId, Component }) => { - const [showTopN, setShowTopN] = useState(false); - const onClick = useCallback(() => setShowTopN(!showTopN), [showTopN]); + const { timelines } = useKibanaServices(); const pageRowIndex = getPageRowIndex(rowIndex, pageSize); if (pageRowIndex >= data.length) { - return null; + // data grid expects each cell action always return an element, it crashes if returns null + return <></>; } const value = getMappedNonEcsValue({ @@ -192,31 +224,20 @@ export const defaultCellActions: TGridCellAction[] = [ fieldName: columnId, }); - const showButton = useMemo( - () => - allowTopN({ - browserField: getAllFieldsByName(browserFields)[columnId], - fieldName: columnId, - hideTopN: false, - }), - [columnId] + return ( + <> + {timelines.getHoverActions().getCopyButton({ + Component, + field: columnId, + isHoverAction: false, + ownFocus: false, + showTooltip: false, + value, + })} + </> ); - - return showButton ? ( - <ShowTopNButton - Component={Component} - enablePopOver - data-test-subj="hover-actions-show-top-n" - field={columnId} - globalFilters={globalFilters} - onClick={onClick} - onFilterAdded={onFilterAdded} - ownFocus={false} - showTopN={showTopN} - showTooltip={false} - timelineId={timelineId} - value={value} - /> - ) : null; }, ]; + +/** the default actions shown in `EuiDataGrid` cells */ +export const defaultCellActions = [...cellActions, ...cellActionLink]; diff --git a/x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.test.tsx b/x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.test.tsx new file mode 100644 index 0000000000000..c818b16ac1f4f --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.test.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { shallow } from 'enzyme'; +import React from 'react'; +import { ExpandedCellValueActions } from './expanded_cell_value_actions'; + +jest.mock('../kibana'); + +describe('ExpandedCellValueActions', () => { + const props = { + browserFields: { + host: { + fields: { + 'host.name': { + aggregatable: true, + category: 'host', + description: + 'Name of the host. It can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use.', + type: 'string', + name: 'host.name', + }, + }, + }, + }, + field: 'host.name', + globalFilters: [], + onFilterAdded: () => {}, + timelineId: 'mockTimelineId', + value: ['mock value'], + }; + const wrapper = shallow(<ExpandedCellValueActions {...props} />); + + test('renders show topN button', () => { + expect(wrapper.find('[data-test-subj="data-grid-expanded-show-top-n"]').exists()).toBeTruthy(); + }); + + test('renders filter in button', () => { + expect(wrapper.find('EuiFlexItem').first().html()).toContain('Filter button'); + }); + + test('renders filter out button', () => { + expect(wrapper.find('EuiFlexItem').last().html()).toContain('Filter out button'); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.tsx b/x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.tsx new file mode 100644 index 0000000000000..4b50fff48fe06 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.tsx @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { noop } from 'lodash/fp'; +import React, { useMemo, useState, useCallback } from 'react'; +import styled from 'styled-components'; +import { Filter } from '../../../../../../../src/plugins/data/public'; +import { BrowserFields } from '../../../../../timelines/common/search_strategy'; +import { allowTopN } from '../../components/drag_and_drop/helpers'; +import { ShowTopNButton } from '../../components/hover_actions/actions/show_top_n'; +import { getAllFieldsByName } from '../../containers/source'; +import { useKibana } from '../kibana'; +import { SHOW_TOP_VALUES, HIDE_TOP_VALUES } from './translations'; + +interface Props { + browserFields: BrowserFields; + field: string; + globalFilters?: Filter[]; + timelineId: string; + value: string[] | undefined; + onFilterAdded?: () => void; +} + +const StyledFlexGroup = styled(EuiFlexGroup)` + border-top: 1px solid #d3dae6; + border-bottom: 1px solid #d3dae6; + margin-top: 2px; +`; + +export const StyledContent = styled.div<{ $isDetails: boolean }>` + padding: ${({ $isDetails }) => ($isDetails ? '0 8px' : undefined)}; +`; + +const ExpandedCellValueActionsComponent: React.FC<Props> = ({ + browserFields, + field, + globalFilters, + onFilterAdded, + timelineId, + value, +}) => { + const { + timelines, + data: { + query: { filterManager }, + }, + } = useKibana().services; + const showButton = useMemo( + () => + allowTopN({ + browserField: getAllFieldsByName(browserFields)[field], + fieldName: field, + hideTopN: false, + }), + [browserFields, field] + ); + + const [showTopN, setShowTopN] = useState(false); + const onClick = useCallback(() => setShowTopN(!showTopN), [showTopN]); + + return ( + <> + <StyledContent $isDetails data-test-subj="data-grid-expanded-cell-value-actions"> + {showButton ? ( + <ShowTopNButton + className="eui-displayBlock expandable-top-value-button" + Component={EuiButtonEmpty} + data-test-subj="data-grid-expanded-show-top-n" + field={field} + flush="both" + globalFilters={globalFilters} + iconSide="right" + iconType={showTopN ? 'arrowUp' : 'arrowDown'} + isExpandable + onClick={onClick} + onFilterAdded={onFilterAdded ?? noop} + ownFocus={false} + paddingSize="none" + showLegend + showTopN={showTopN} + showTooltip={false} + timelineId={timelineId} + title={showTopN ? HIDE_TOP_VALUES : SHOW_TOP_VALUES} + value={value} + /> + ) : null} + </StyledContent> + <StyledFlexGroup gutterSize="s"> + <EuiFlexItem> + {timelines.getHoverActions().getFilterForValueButton({ + Component: EuiButtonEmpty, + field, + filterManager, + onFilterAdded, + ownFocus: false, + size: 's', + showTooltip: false, + value, + })} + </EuiFlexItem> + <EuiFlexItem> + {timelines.getHoverActions().getFilterOutValueButton({ + Component: EuiButtonEmpty, + field, + filterManager, + onFilterAdded, + ownFocus: false, + size: 's', + showTooltip: false, + value, + })} + </EuiFlexItem> + </StyledFlexGroup> + </> + ); +}; + +ExpandedCellValueActionsComponent.displayName = 'ExpandedCellValueActionsComponent'; + +export const ExpandedCellValueActions = React.memo(ExpandedCellValueActionsComponent); diff --git a/x-pack/plugins/security_solution/public/common/lib/cell_actions/helpers.ts b/x-pack/plugins/security_solution/public/common/lib/cell_actions/helpers.ts new file mode 100644 index 0000000000000..1c40d8df48bfe --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/lib/cell_actions/helpers.ts @@ -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 * as i18n from './translations'; +import { + EVENT_URL_FIELD_NAME, + HOST_NAME_FIELD_NAME, + REFERENCE_URL_FIELD_NAME, + RULE_REFERENCE_FIELD_NAME, + SIGNAL_RULE_NAME_FIELD_NAME, +} from '../../../timelines/components/timeline/body/renderers/constants'; +import { INDICATOR_REFERENCE } from '../../../../common/cti/constants'; +import { IP_FIELD_TYPE } from '../../../network/components/ip'; +import { PORT_NAMES } from '../../../network/components/port/helpers'; + +export const COLUMNS_WITH_LINKS = [ + { + columnId: HOST_NAME_FIELD_NAME, + label: i18n.VIEW_HOST_SUMMARY, + }, + { + columnId: 'source.ip', + fieldType: IP_FIELD_TYPE, + label: i18n.EXPAND_IP_DETAILS, + }, + { + columnId: 'destination.ip', + fieldType: IP_FIELD_TYPE, + label: i18n.EXPAND_IP_DETAILS, + }, + { + columnId: SIGNAL_RULE_NAME_FIELD_NAME, + label: i18n.VIEW_RULE_DETAILS, + }, + ...PORT_NAMES.map((p) => ({ + columnId: p, + label: i18n.VIEW_PORT_DETAILS, + })), + { + columnId: RULE_REFERENCE_FIELD_NAME, + label: i18n.VIEW_RULE_REFERENCE, + }, + { + columnId: REFERENCE_URL_FIELD_NAME, + label: i18n.VIEW_RULE_REFERENCE, + }, + { + columnId: EVENT_URL_FIELD_NAME, + label: i18n.VIEW_EVENT_REFERENCE, + }, + { + columnId: INDICATOR_REFERENCE, + label: i18n.VIEW_INDICATOR_REFERENCE, + }, +]; + +export const getLink = (cId?: string, fieldType?: string, linkField?: string) => + cId && + COLUMNS_WITH_LINKS.find( + (c) => c.columnId === cId || (c.fieldType && fieldType === c.fieldType && linkField != null) + ); diff --git a/x-pack/plugins/security_solution/public/common/lib/cell_actions/translations.ts b/x-pack/plugins/security_solution/public/common/lib/cell_actions/translations.ts new file mode 100644 index 0000000000000..527cc14c323b2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/lib/cell_actions/translations.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SHOW_TOP_VALUES = i18n.translate( + 'xpack.securitySolution.expandedValue.showTopN.showTopValues', + { + defaultMessage: 'Show top values', + } +); + +export const HIDE_TOP_VALUES = i18n.translate( + 'xpack.securitySolution.expandedValue.hideTopValues.HideTopValues', + { + defaultMessage: 'Hide top values', + } +); + +export const VIEW_HOST_SUMMARY = i18n.translate( + 'xpack.securitySolution.expandedValue.links.viewHostSummary', + { + defaultMessage: 'View host summary', + } +); + +export const EXPAND_IP_DETAILS = i18n.translate( + 'xpack.securitySolution.expandedValue.links.expandIpDetails', + { + defaultMessage: 'Expand ip details', + } +); + +export const VIEW_RULE_DETAILS = i18n.translate( + 'xpack.securitySolution.expandedValue.links.viewRuleDetails', + { + defaultMessage: 'View rule details', + } +); + +export const VIEW_PORT_DETAILS = i18n.translate( + 'xpack.securitySolution.expandedValue.links.viewPortDetails', + { + defaultMessage: 'View port details', + } +); + +export const VIEW_RULE_REFERENCE = i18n.translate( + 'xpack.securitySolution.expandedValue.links.viewRuleReference', + { + defaultMessage: 'View rule reference', + } +); + +export const VIEW_EVENT_REFERENCE = i18n.translate( + 'xpack.securitySolution.expandedValue.links.viewEventReference', + { + defaultMessage: 'View event reference', + } +); + +export const VIEW_INDICATOR_REFERENCE = i18n.translate( + 'xpack.securitySolution.expandedValue.links.viewIndicatorReference', + { + defaultMessage: 'View indicator reference', + } +); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/alerts_histogram.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/alerts_histogram.tsx index 09d8d52271674..d09d33ce5aded 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/alerts_histogram.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/alerts_histogram.tsx @@ -31,6 +31,7 @@ interface AlertsHistogramProps { legendItems: LegendItem[]; legendPosition?: Position; loading: boolean; + showLegend?: boolean; to: string; data: HistogramData[]; updateDateRange: UpdateDateRange; @@ -43,6 +44,7 @@ export const AlertsHistogram = React.memo<AlertsHistogramProps>( legendItems, legendPosition = 'right', loading, + showLegend, to, updateDateRange, }) => { @@ -73,8 +75,9 @@ export const AlertsHistogram = React.memo<AlertsHistogramProps>( <Settings legendPosition={legendPosition} onBrushEnd={updateDateRange} - showLegend={legendItems.length === 0} - showLegendExtra + // showLegend controls the default legend coming from Elastic chart, we show them when our customised legend items doesn't exist (but we still want to show legend). + showLegend={showLegend && legendItems.length === 0} + showLegendExtra={showLegend} theme={theme} /> diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx index 280b7f2926276..0613c619d89b9 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx @@ -63,10 +63,12 @@ interface AlertsHistogramPanelProps { headerChildren?: React.ReactNode; /** Override all defaults, and only display this field */ onlyField?: AlertsStackByField; + paddingSize?: 's' | 'm' | 'l' | 'none'; titleSize?: EuiTitleSize; query?: Query; legendPosition?: Position; signalIndexName: string | null; + showLegend?: boolean; showLinkToAlerts?: boolean; showTotalAlertsCount?: boolean; showStackBy?: boolean; @@ -85,9 +87,11 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>( filters, headerChildren, onlyField, + paddingSize = 'm', query, legendPosition = 'right', signalIndexName, + showLegend = true, showLinkToAlerts = false, showTotalAlertsCount = false, showStackBy = true, @@ -154,7 +158,7 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>( const legendItems: LegendItem[] = useMemo( () => - alertsData?.aggregations?.alertsByGrouping?.buckets != null + showLegend && alertsData?.aggregations?.alertsByGrouping?.buckets != null ? alertsData.aggregations.alertsByGrouping.buckets.map((bucket, i) => ({ color: i < defaultLegendColors.length ? defaultLegendColors[i] : undefined, dataProviderId: escapeDataProviderId( @@ -165,7 +169,12 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>( value: bucket.key, })) : NO_LEGEND_DATA, - [alertsData, selectedStackByOption, timelineId] + [ + alertsData?.aggregations?.alertsByGrouping.buckets, + selectedStackByOption, + showLegend, + timelineId, + ] ); useEffect(() => { @@ -254,7 +263,7 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>( return ( <InspectButtonContainer data-test-subj="alerts-histogram-panel" show={!isInitialLoading}> - <KpiPanel height={PANEL_HEIGHT} hasBorder> + <KpiPanel height={PANEL_HEIGHT} hasBorder paddingSize={paddingSize}> <HeaderSection id={uniqueQueryId} title={titleText} @@ -288,6 +297,7 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>( legendPosition={legendPosition} loading={isLoadingAlerts} to={to} + showLegend={showLegend} updateDateRange={updateDateRange} /> )} diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 89d0fd2e4dbd0..d7c48c4f18bc8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -375,21 +375,21 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({ return ( <StatefulEventsViewer - pageFilters={defaultFiltersMemo} + additionalFilters={additionalFiltersComponent} + currentFilter={filterGroup} defaultCellActions={defaultCellActions} defaultModel={defaultTimelineModel} - entityType="events" end={to} - currentFilter={filterGroup} + entityType="events" + hasAlertsCrud={hasIndexWrite && hasIndexMaintenance} id={timelineId} onRuleChange={onRuleChange} + pageFilters={defaultFiltersMemo} renderCellValue={RenderCellValue} rowRenderers={defaultRowRenderers} scopeId={SourcererScopeName.detections} start={from} utilityBar={utilityBarCallback} - additionalFilters={additionalFiltersComponent} - hasAlertsCrud={hasIndexWrite && hasIndexMaintenance} /> ); }; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.tsx b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.tsx index d9cdc4e0d0912..54cd26e9cdc54 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.tsx +++ b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.tsx @@ -18,37 +18,41 @@ import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell */ export const RenderCellValue: React.FC<EuiDataGridCellValueElementProps & CellValueElementProps> = ({ + browserFields, columnId, data, + ecsData, eventId, - isDraggable, + globalFilters, header, isDetails, + isDraggable, isExpandable, isExpanded, linkValues, rowIndex, + rowRenderers, setCellProps, timelineId, - ecsData, - rowRenderers, - browserFields, + truncate, }) => ( <DefaultCellRenderer + browserFields={browserFields} columnId={columnId} data={data} + ecsData={ecsData} eventId={eventId} - isDraggable={isDraggable} + globalFilters={globalFilters} header={header} isDetails={isDetails} + isDraggable={isDraggable} isExpandable={isExpandable} isExpanded={isExpanded} linkValues={linkValues} rowIndex={rowIndex} + rowRenderers={rowRenderers} setCellProps={setCellProps} timelineId={timelineId} - ecsData={ecsData} - rowRenderers={rowRenderers} - browserFields={browserFields} + truncate={truncate} /> ); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx index cbab24835c1ac..40894c1d01929 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx @@ -86,7 +86,12 @@ const userPrivilegesInitial: ReturnType<typeof useUserPrivileges> = { result: undefined, error: undefined, }, - endpointPrivileges: { loading: true, canAccessEndpointManagement: false, canAccessFleet: false }, + endpointPrivileges: { + loading: true, + canAccessEndpointManagement: false, + canAccessFleet: false, + isPlatinumPlus: true, + }, kibanaSecuritySolutionsPrivileges: { crud: true, read: true }, }; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts index 9faed2d0646e0..ecf68fa207b70 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts @@ -108,6 +108,8 @@ export const RuleSchema = t.intersection([ throttle: t.union([t.string, t.null]), }), t.partial({ + outcome: t.union([t.literal('exactMatch'), t.literal('aliasMatch'), t.literal('conflict')]), + alias_target_id: t.string, building_block_type, anomaly_threshold: t.number, filters: t.array(t.unknown), diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.test.tsx index d95b6ca9f3435..c91aade50cbae 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.test.tsx @@ -6,19 +6,79 @@ */ import React from 'react'; -import { shallow } from 'enzyme'; - -import { TestProviders } from '../../../../../common/mock'; +import { shallow, mount } from 'enzyme'; +import { + TestProviders, + createSecuritySolutionStorageMock, + kibanaObservable, + mockGlobalState, + SUB_PLUGINS_REDUCER, +} from '../../../../../common/mock'; import { FailureHistory } from './failure_history'; import { useRuleStatus } from '../../../../containers/detection_engine/rules'; jest.mock('../../../../containers/detection_engine/rules'); +import { waitFor } from '@testing-library/react'; + +import '../../../../../common/mock/match_media'; + +import { createStore, State } from '../../../../../common/store'; +import { mockHistory, Router } from '../../../../../common/mock/router'; + +const state: State = { + ...mockGlobalState, +}; +const { storage } = createSecuritySolutionStorageMock(); +const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); + +describe('RuleDetailsPageComponent', () => { + beforeAll(() => { + (useRuleStatus as jest.Mock).mockReturnValue([ + false, + { + status: 'succeeded', + last_failure_at: new Date().toISOString(), + last_failure_message: 'my fake failure message', + failures: [ + { + alert_id: 'myfakeid', + status_date: new Date().toISOString(), + status: 'failed', + last_failure_at: new Date().toISOString(), + last_success_at: new Date().toISOString(), + last_failure_message: 'my fake failure message', + last_look_back_date: new Date().toISOString(), // NOTE: This is no longer used on the UI, but left here in case users are using it within the API + }, + ], + }, + ]); + }); + + it('renders reported rule failures correctly', async () => { + const wrapper = mount( + <TestProviders store={store}> + <Router history={mockHistory}> + <FailureHistory id="id" /> + </Router> + </TestProviders> + ); + + await waitFor(() => { + expect(wrapper.find('EuiBasicTable')).toHaveLength(1); + // ensure the expected error message is displayed in the table + expect(wrapper.find('EuiTableRowCell').at(2).find('div').at(1).text()).toEqual( + 'my fake failure message' + ); + }); + }); +}); + describe('FailureHistory', () => { beforeAll(() => { (useRuleStatus as jest.Mock).mockReturnValue([false, null]); }); - it('renders correctly', () => { + it('renders correctly with no statuses', () => { const wrapper = shallow(<FailureHistory id="id" />, { wrappingComponent: TestProviders, }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx index a7db7ab57f6c2..5289e34b10046 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx @@ -23,6 +23,12 @@ interface FailureHistoryProps { id?: string | null; } +const renderStatus = () => <EuiHealth color="danger">{i18n.TYPE_FAILED}</EuiHealth>; +const renderLastFailureAt = (value: string) => ( + <FormattedDate value={value} fieldName="last_failure_at" /> +); +const renderLastFailureMessage = (value: string) => <>{value}</>; + const FailureHistoryComponent: React.FC<FailureHistoryProps> = ({ id }) => { const [loading, ruleStatus] = useRuleStatus(id); if (loading) { @@ -36,14 +42,14 @@ const FailureHistoryComponent: React.FC<FailureHistoryProps> = ({ id }) => { const columns: Array<EuiBasicTableColumn<RuleInfoStatus>> = [ { name: i18n.COLUMN_STATUS_TYPE, - render: () => <EuiHealth color="danger">{i18n.TYPE_FAILED}</EuiHealth>, + render: renderStatus, truncateText: false, width: '16%', }, { field: 'last_failure_at', name: i18n.COLUMN_FAILED_AT, - render: (value: string) => <FormattedDate value={value} fieldName="last_failure_at" />, + render: renderLastFailureAt, sortable: false, truncateText: false, width: '24%', @@ -51,7 +57,7 @@ const FailureHistoryComponent: React.FC<FailureHistoryProps> = ({ id }) => { { field: 'last_failure_message', name: i18n.COLUMN_FAILED_MSG, - render: (value: string) => <>{value}</>, + render: renderLastFailureMessage, sortable: false, truncateText: false, width: '60%', diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx index 0c67a19e59e32..9c1667e7b4910 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx @@ -20,22 +20,51 @@ import { import { RuleDetailsPage } from './index'; import { createStore, State } from '../../../../../common/store'; import { useUserData } from '../../../../components/user_info'; +import { useRuleStatus } from '../../../../containers/detection_engine/rules'; +import { useRuleWithFallback } from '../../../../containers/detection_engine/rules/use_rule_with_fallback'; + import { useSourcererScope } from '../../../../../common/containers/sourcerer'; import { useParams } from 'react-router-dom'; import { mockHistory, Router } from '../../../../../common/mock/router'; -import { mockTimelines } from '../../../../../common/mock/mock_timelines_plugin'; + +import { useKibana } from '../../../../../common/lib/kibana'; + +import { fillEmptySeverityMappings } from '../helpers'; // Test will fail because we will to need to mock some core services to make the test work // For now let's forget about SiemSearchBar and QueryBar jest.mock('../../../../../common/components/search_bar', () => ({ SiemSearchBar: () => null, })); +jest.mock('../helpers', () => { + const original = jest.requireActual('../helpers'); + return { + ...original, + fillEmptySeverityMappings: jest.fn().mockReturnValue([]), + }; +}); jest.mock('../../../../../common/components/query_bar', () => ({ QueryBar: () => null, })); jest.mock('../../../../containers/detection_engine/lists/use_lists_config'); jest.mock('../../../../../common/components/link_to'); jest.mock('../../../../components/user_info'); +jest.mock('../../../../containers/detection_engine/rules', () => { + const original = jest.requireActual('../../../../containers/detection_engine/rules'); + return { + ...original, + useRuleStatus: jest.fn(), + }; +}); +jest.mock('../../../../containers/detection_engine/rules/use_rule_with_fallback', () => { + const original = jest.requireActual( + '../../../../containers/detection_engine/rules/use_rule_with_fallback' + ); + return { + ...original, + useRuleWithFallback: jest.fn(), + }; +}); jest.mock('../../../../../common/containers/sourcerer'); jest.mock('../../../../../common/containers/use_global_time', () => ({ useGlobalTime: jest.fn().mockReturnValue({ @@ -55,41 +84,42 @@ jest.mock('react-router-dom', () => { }; }); -jest.mock('../../../../../common/lib/kibana', () => { - const original = jest.requireActual('../../../../../common/lib/kibana'); +jest.mock('../../../../../common/lib/kibana'); - return { - ...original, - useUiSetting$: jest.fn().mockReturnValue([]), - useKibana: () => ({ - services: { - application: { - ...original.useKibana().services.application, - navigateToUrl: jest.fn(), - capabilities: { - actions: jest.fn().mockReturnValue({}), - siem: { crud_alerts: true, read_alerts: true }, - }, - }, - timelines: { ...mockTimelines }, - data: { - query: { - filterManager: jest.fn().mockReturnValue({}), - }, - }, - }, - }), - useToasts: jest.fn().mockReturnValue({ - addError: jest.fn(), - addSuccess: jest.fn(), - addWarning: jest.fn(), - }), - }; -}); +const mockRedirectLegacyUrl = jest.fn(); +const mockGetLegacyUrlConflict = jest.fn(); const state: State = { ...mockGlobalState, }; + +const mockRule = { + id: 'myfakeruleid', + author: [], + severity_mapping: [], + risk_score_mapping: [], + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + references: [], + actions: [], + enabled: false, + false_positives: [], + max_signals: 100, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], +}; const { storage } = createSecuritySolutionStorageMock(); const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); @@ -101,9 +131,108 @@ describe('RuleDetailsPageComponent', () => { indicesExist: true, indexPattern: {}, }); + (useRuleStatus as jest.Mock).mockReturnValue([ + false, + { + status: 'succeeded', + last_failure_at: new Date().toISOString(), + last_failure_message: 'my fake failure message', + failures: [], + }, + ]); + (useRuleWithFallback as jest.Mock).mockReturnValue({ + error: null, + loading: false, + isExistingRule: true, + refresh: jest.fn(), + rule: { ...mockRule }, + }); + (fillEmptySeverityMappings as jest.Mock).mockReturnValue([]); + }); + + async function setup() { + const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>; + + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.spaces = { + ui: { + // @ts-expect-error + components: { getLegacyUrlConflict: mockGetLegacyUrlConflict }, + redirectLegacyUrl: mockRedirectLegacyUrl, + }, + }; + } + + it('renders correctly with no outcome property on rule', async () => { + await setup(); + + const wrapper = mount( + <TestProviders store={store}> + <Router history={mockHistory}> + <RuleDetailsPage /> + </Router> + </TestProviders> + ); + await waitFor(() => { + expect(wrapper.find('[data-test-subj="header-page-title"]').exists()).toBe(true); + expect(mockRedirectLegacyUrl).not.toHaveBeenCalled(); + }); + }); + + it('renders correctly with outcome === "exactMatch"', async () => { + await setup(); + (useRuleWithFallback as jest.Mock).mockReturnValue({ + error: null, + loading: false, + isExistingRule: true, + refresh: jest.fn(), + rule: { ...mockRule, outcome: 'exactMatch' }, + }); + + const wrapper = mount( + <TestProviders store={store}> + <Router history={mockHistory}> + <RuleDetailsPage /> + </Router> + </TestProviders> + ); + await waitFor(() => { + expect(wrapper.find('[data-test-subj="header-page-title"]').exists()).toBe(true); + expect(mockRedirectLegacyUrl).not.toHaveBeenCalled(); + }); }); - it('renders correctly', async () => { + it('renders correctly with outcome === "aliasMatch"', async () => { + await setup(); + (useRuleWithFallback as jest.Mock).mockReturnValue({ + error: null, + loading: false, + isExistingRule: true, + refresh: jest.fn(), + rule: { ...mockRule, outcome: 'aliasMatch' }, + }); + const wrapper = mount( + <TestProviders store={store}> + <Router history={mockHistory}> + <RuleDetailsPage /> + </Router> + </TestProviders> + ); + await waitFor(() => { + expect(wrapper.find('[data-test-subj="header-page-title"]').exists()).toBe(true); + expect(mockRedirectLegacyUrl).toHaveBeenCalledWith(`rules/id/myfakeruleid`, `rule`); + }); + }); + + it('renders correctly when outcome = conflict', async () => { + await setup(); + (useRuleWithFallback as jest.Mock).mockReturnValue({ + error: null, + loading: false, + isExistingRule: true, + refresh: jest.fn(), + rule: { ...mockRule, outcome: 'conflict', alias_target_id: 'aliased_rule_id' }, + }); const wrapper = mount( <TestProviders store={store}> <Router history={mockHistory}> @@ -113,6 +242,13 @@ describe('RuleDetailsPageComponent', () => { ); await waitFor(() => { expect(wrapper.find('[data-test-subj="header-page-title"]').exists()).toBe(true); + expect(mockRedirectLegacyUrl).toHaveBeenCalledWith(`rules/id/myfakeruleid`, `rule`); + expect(mockGetLegacyUrlConflict).toHaveBeenCalledWith({ + currentObjectId: 'myfakeruleid', + objectNoun: 'rule', + otherObjectId: 'aliased_rule_id', + otherObjectPath: `rules/id/aliased_rule_id`, + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 70d7faa47b9ee..492b8e461fb60 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -19,6 +19,8 @@ import { EuiToolTip, EuiWindowEvent, } from '@elastic/eui'; +import { i18n as i18nTranslate } from '@kbn/i18n'; + import { FormattedMessage } from '@kbn/i18n/react'; import { noop } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; @@ -261,6 +263,7 @@ const RuleDetailsPageComponent: React.FC<DetectionEngineComponentProps> = ({ capabilities: { actions }, }, timelines: timelinesUi, + spaces: spacesApi, }, } = useKibana(); const hasActionsPrivileges = useMemo(() => { @@ -277,6 +280,52 @@ const RuleDetailsPageComponent: React.FC<DetectionEngineComponentProps> = ({ } }, [maybeRule]); + useEffect(() => { + if (rule) { + const outcome = rule.outcome; + if (spacesApi && outcome === 'aliasMatch') { + // This rule has been resolved from a legacy URL - redirect the user to the new URL and display a toast. + const path = `rules/id/${rule.id}${window.location.search}${window.location.hash}`; + spacesApi.ui.redirectLegacyUrl( + path, + i18nTranslate.translate( + 'xpack.triggersActionsUI.sections.alertDetails.redirectObjectNoun', + { + defaultMessage: 'rule', + } + ) + ); + } + } + }, [rule, spacesApi]); + + const getLegacyUrlConflictCallout = useMemo(() => { + const outcome = rule?.outcome; + if (rule != null && spacesApi && outcome === 'conflict') { + const aliasTargetId = rule?.alias_target_id!; // This is always defined if outcome === 'conflict' + // We have resolved to one rule, but there is another one with a legacy URL associated with this page. Display a + // callout with a warning for the user, and provide a way for them to navigate to the other rule. + const otherRulePath = `rules/id/${aliasTargetId}${window.location.search}${window.location.hash}`; + return ( + <> + <EuiSpacer /> + {spacesApi.ui.components.getLegacyUrlConflict({ + objectNoun: i18nTranslate.translate( + 'xpack.triggersActionsUI.sections.alertDetails.redirectObjectNoun', + { + defaultMessage: 'rule', + } + ), + currentObjectId: rule.id, + otherObjectId: aliasTargetId, + otherObjectPath: otherRulePath, + })} + </> + ); + } + return null; + }, [rule, spacesApi]); + useEffect(() => { if (!hasIndexRead) { setTabs(ruleDetailTabs.filter(({ id }) => id !== RuleDetailTabs.alerts)); @@ -721,6 +770,7 @@ const RuleDetailsPageComponent: React.FC<DetectionEngineComponentProps> = ({ </EuiFlexGroup> </DetectionEngineHeaderPage> {ruleError} + {getLegacyUrlConflictCallout} <EuiSpacer /> <EuiFlexGroup> <EuiFlexItem data-test-subj="aboutRule" component="section" grow={1}> diff --git a/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx b/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx index fb3e22260bd84..3a27f8c2f3ba6 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx @@ -115,11 +115,11 @@ const EventsQueryTabBodyComponent: React.FC<HostsComponentsQueryProps> = ({ end={endDate} entityType="events" id={TimelineId.hostsPageEvents} + pageFilters={pageFilters} renderCellValue={DefaultCellRenderer} rowRenderers={defaultRowRenderers} scopeId={SourcererScopeName.default} start={startDate} - pageFilters={pageFilters} unit={unit} /> </> diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx index 52299679ec87b..bde1961dd782d 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx @@ -25,7 +25,7 @@ describe.each([ ) => ReturnType<AppContextTestRender['render']>; beforeEach(() => { - item = generateItem(); + item = generateItem() as AnyArtifact; appTestContext = createAppRootMockRenderer(); render = (props = {}) => { renderResult = appTestContext.render( @@ -77,13 +77,31 @@ describe.each([ expect(renderResult.getByTestId('testCard-description').textContent).toEqual(item.description); }); + it("shouldn't display description", async () => { + render({ hideDescription: true }); + expect(renderResult.queryByTestId('testCard-description')).toBeNull(); + }); + it('should display default empty value if description does not exist', async () => { item.description = undefined; render(); - expect(renderResult.getByTestId('testCard-description').textContent).toEqual('—'); }); + it('should display comments if one exists', async () => { + render(); + if (isTrustedApp(item)) { + expect(renderResult.queryByTestId('testCard-comments')).toBeNull(); + } else { + expect(renderResult.queryByTestId('testCard-comments')).not.toBeNull(); + } + }); + + it("shouldn't display comments", async () => { + render({ hideComments: true }); + expect(renderResult.queryByTestId('testCard-comments')).toBeNull(); + }); + it('should display OS and criteria conditions', () => { render(); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx index d9709c64e092d..bee9a63c9cf69 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx @@ -16,10 +16,11 @@ import { useNormalizedArtifact } from './hooks/use_normalized_artifact'; import { useTestIdGenerator } from '../hooks/use_test_id_generator'; import { CardContainerPanel } from './components/card_container_panel'; import { CardSectionPanel } from './components/card_section_panel'; +import { CardComments } from './components/card_comments'; import { usePolicyNavLinks } from './hooks/use_policy_nav_links'; import { MaybeImmutable } from '../../../../common/endpoint/types'; -export interface ArtifactEntryCardProps extends CommonProps { +export interface CommonArtifactEntryCardProps extends CommonProps { item: MaybeImmutable<AnyArtifact>; /** * The list of actions for the card. Will display an icon with the actions in a menu if defined. @@ -34,12 +35,27 @@ export interface ArtifactEntryCardProps extends CommonProps { policies?: MenuItemPropsByPolicyId; } +export interface ArtifactEntryCardProps extends CommonArtifactEntryCardProps { + // A flag to hide description section, false by default + hideDescription?: boolean; + // A flag to hide comments section, false by default + hideComments?: boolean; +} + /** * Display Artifact Items (ex. Trusted App, Event Filter, etc) as a card. * This component is a TS Generic that allows you to set what the Item type is */ export const ArtifactEntryCard = memo<ArtifactEntryCardProps>( - ({ item, policies, actions, 'data-test-subj': dataTestSubj, ...commonProps }) => { + ({ + item, + policies, + actions, + hideDescription = false, + hideComments = false, + 'data-test-subj': dataTestSubj, + ...commonProps + }) => { const artifact = useNormalizedArtifact(item as AnyArtifact); const getTestId = useTestIdGenerator(dataTestSubj); const policyNavLinks = usePolicyNavLinks(artifact, policies); @@ -63,11 +79,16 @@ export const ArtifactEntryCard = memo<ArtifactEntryCardProps>( <EuiSpacer size="m" /> - <EuiText> - <p data-test-subj={getTestId('description')}> - {artifact.description || getEmptyValue()} - </p> - </EuiText> + {!hideDescription ? ( + <EuiText> + <p data-test-subj={getTestId('description')}> + {artifact.description || getEmptyValue()} + </p> + </EuiText> + ) : null} + {!hideComments ? ( + <CardComments comments={artifact.comments} data-test-subj={getTestId('comments')} /> + ) : null} </CardSectionPanel> <EuiHorizontalRule margin="none" /> diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx index 43572ea234d31..673504c18a9df 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx @@ -7,7 +7,7 @@ import React, { memo } from 'react'; import { EuiHorizontalRule } from '@elastic/eui'; -import { ArtifactEntryCardProps } from './artifact_entry_card'; +import { CommonArtifactEntryCardProps } from './artifact_entry_card'; import { CardContainerPanel } from './components/card_container_panel'; import { useNormalizedArtifact } from './hooks/use_normalized_artifact'; import { useTestIdGenerator } from '../hooks/use_test_id_generator'; @@ -15,7 +15,7 @@ import { CardSectionPanel } from './components/card_section_panel'; import { CriteriaConditions, CriteriaConditionsProps } from './components/criteria_conditions'; import { CardCompressedHeader } from './components/card_compressed_header'; -export interface ArtifactEntryCollapsibleCardProps extends ArtifactEntryCardProps { +export interface ArtifactEntryCollapsibleCardProps extends CommonArtifactEntryCardProps { onExpandCollapse: () => void; expanded?: boolean; } diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx new file mode 100644 index 0000000000000..ce539554a722e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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, useMemo, useCallback, useState } from 'react'; +import { + CommonProps, + EuiAccordion, + EuiCommentList, + EuiCommentProps, + EuiButtonEmpty, + EuiSpacer, +} from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; +import { CardActionsFlexItemProps } from './card_actions_flex_item'; +import { ArtifactInfo } from '../types'; +import { getFormattedComments } from '../utils/get_formatted_comments'; +import { SHOW_COMMENTS_LABEL, HIDE_COMMENTS_LABEL } from './translations'; + +export interface CardCommentsProps + extends CardActionsFlexItemProps, + Pick<CommonProps, 'data-test-subj'> { + comments: ArtifactInfo['comments']; +} + +export const CardComments = memo<CardCommentsProps>( + ({ comments, 'data-test-subj': dataTestSubj }) => { + const getTestId = useTestIdGenerator(dataTestSubj); + + const [showComments, setShowComments] = useState(false); + const onCommentsClick = useCallback((): void => { + setShowComments(!showComments); + }, [setShowComments, showComments]); + const formattedComments = useMemo((): EuiCommentProps[] => { + return getFormattedComments(comments); + }, [comments]); + + const buttonText = useMemo( + () => + showComments ? HIDE_COMMENTS_LABEL(comments.length) : SHOW_COMMENTS_LABEL(comments.length), + [comments.length, showComments] + ); + + return !isEmpty(comments) ? ( + <div data-test-subj={dataTestSubj}> + <EuiSpacer size="s" /> + <EuiButtonEmpty + onClick={onCommentsClick} + flush="left" + size="xs" + data-test-subj={getTestId('label')} + > + {buttonText} + </EuiButtonEmpty> + <EuiAccordion id={'1'} arrowDisplay="none" forceState={showComments ? 'open' : 'closed'}> + <EuiSpacer size="m" /> + <EuiCommentList comments={formattedComments} data-test-subj={getTestId('list')} /> + </EuiAccordion> + </div> + ) : null; + } +); + +CardComments.displayName = 'CardComments'; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx index 292c06c4f5b8c..260db313ced36 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx @@ -5,8 +5,9 @@ * 2.0. */ -import React, { memo } from 'react'; -import { CommonProps, EuiExpression } from '@elastic/eui'; +import React, { memo, useCallback } from 'react'; +import { CommonProps, EuiExpression, EuiToken, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import styled from 'styled-components'; import { ListOperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { CONDITION_OS, @@ -21,7 +22,7 @@ import { CONDITION_OPERATOR_TYPE_EXISTS, CONDITION_OPERATOR_TYPE_LIST, } from './translations'; -import { ArtifactInfo } from '../types'; +import { ArtifactInfo, ArtifactInfoEntry } from '../types'; import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; const OS_LABELS = Object.freeze({ @@ -39,6 +40,15 @@ const OPERATOR_TYPE_LABELS = Object.freeze({ [ListOperatorTypeEnum.LIST]: CONDITION_OPERATOR_TYPE_LIST, }); +const EuiFlexGroupNested = styled(EuiFlexGroup)` + margin-left: ${({ theme }) => theme.eui.spacerSizes.l}; +`; + +const EuiFlexItemNested = styled(EuiFlexItem)` + margin-bottom: 6px !important; + margin-top: 6px !important; +`; + export type CriteriaConditionsProps = Pick<ArtifactInfo, 'os' | 'entries'> & Pick<CommonProps, 'data-test-subj'>; @@ -46,6 +56,44 @@ export const CriteriaConditions = memo<CriteriaConditionsProps>( ({ os, entries, 'data-test-subj': dataTestSubj }) => { const getTestId = useTestIdGenerator(dataTestSubj); + const getNestedEntriesContent = useCallback( + (type: string, nestedEntries: ArtifactInfoEntry[]) => { + if (type === 'nested' && nestedEntries.length) { + return nestedEntries.map( + ({ field: nestedField, type: nestedType, value: nestedValue }) => { + return ( + <EuiFlexGroupNested + data-test-subj={getTestId('nestedCondition')} + key={nestedField + nestedType + nestedValue} + direction="row" + alignItems="center" + gutterSize="m" + responsive={false} + > + <EuiFlexItemNested grow={false}> + <EuiToken iconType="tokenNested" size="s" /> + </EuiFlexItemNested> + <EuiFlexItemNested grow={false}> + <EuiExpression description={''} value={nestedField} color="subdued" /> + </EuiFlexItemNested> + <EuiFlexItemNested grow={false}> + <EuiExpression + description={ + OPERATOR_TYPE_LABELS[nestedType as keyof typeof OPERATOR_TYPE_LABELS] ?? + nestedType + } + value={nestedValue} + /> + </EuiFlexItemNested> + </EuiFlexGroupNested> + ); + } + ); + } + }, + [getTestId] + ); + return ( <div data-test-subj={dataTestSubj}> <div data-test-subj={getTestId('os')}> @@ -57,7 +105,7 @@ export const CriteriaConditions = memo<CriteriaConditionsProps>( /> </strong> </div> - {entries.map(({ field, type, value }) => { + {entries.map(({ field, type, value, entries: nestedEntries = [] }) => { return ( <div data-test-subj={getTestId('condition')} key={field + type + value}> <EuiExpression description={CONDITION_AND} value={field} color="subdued" /> @@ -67,6 +115,7 @@ export const CriteriaConditions = memo<CriteriaConditionsProps>( } value={value} /> + {getNestedEntriesContent(type, nestedEntries)} </div> ); })} diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts index d98f4589027d4..512724b66d50e 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts @@ -114,3 +114,15 @@ export const COLLAPSE_ACTION = i18n.translate( defaultMessage: 'Collapse', } ); + +export const SHOW_COMMENTS_LABEL = (count: number = 0) => + i18n.translate('xpack.securitySolution.artifactCard.comments.label.show', { + defaultMessage: 'Show comments ({count})', + values: { count }, + }); + +export const HIDE_COMMENTS_LABEL = (count: number = 0) => + i18n.translate('xpack.securitySolution.artifactCard.comments.label.hide', { + defaultMessage: 'Hide comments ({count})', + values: { count }, + }); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts index d9ff23b3a2c6a..d7d8899b005ed 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts @@ -6,6 +6,7 @@ */ import { cloneDeep } from 'lodash'; +import uuid from 'uuid'; import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { TrustedAppGenerator } from '../../../../common/endpoint/data_generators/trusted_app_generator'; import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; @@ -54,6 +55,14 @@ export const getExceptionProviderMock = (): ExceptionListItemSchema => { }, ], tags: ['policy:all'], + comments: [ + { + id: uuid.v4(), + comment: 'test', + created_at: new Date().toISOString(), + created_by: 'Justa', + }, + ], }) ); }; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts index c506c62ac4351..fe50a15190f11 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts @@ -10,6 +10,13 @@ import { EffectScope, TrustedApp } from '../../../../common/endpoint/types'; import { ContextMenuItemNavByRouterProps } from '../context_menu_with_router_support/context_menu_item_nav_by_router'; export type AnyArtifact = ExceptionListItemSchema | TrustedApp; +export interface ArtifactInfoEntry { + field: string; + type: string; + operator: string; + value: string; +} +type ArtifactInfoEntries = ArtifactInfoEntry & { entries?: ArtifactInfoEntry[] }; /** * A normalized structured that is used internally through out the card's components. @@ -17,16 +24,11 @@ export type AnyArtifact = ExceptionListItemSchema | TrustedApp; export interface ArtifactInfo extends Pick< ExceptionListItemSchema, - 'name' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by' | 'description' + 'name' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by' | 'description' | 'comments' > { effectScope: EffectScope; os: string; - entries: Array<{ - field: string; - type: string; - operator: string; - value: string; - }>; + entries: ArtifactInfoEntries[]; } export interface MenuItemPropsByPolicyId { diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.tsx new file mode 100644 index 0000000000000..c9e96c5ce9ec1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.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 React from 'react'; +import { EuiAvatar, EuiText, EuiCommentProps } from '@elastic/eui'; +import styled from 'styled-components'; +import { CommentsArray } from '@kbn/securitysolution-io-ts-list-types'; +import { COMMENT_EVENT } from '../../../../common/components/exceptions/translations'; +import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; + +const CustomEuiAvatar = styled(EuiAvatar)` + background-color: ${({ theme }) => theme.eui.euiColorLightShade} !important; +`; + +/** + * Formats ExceptionItem.comments into EuiCommentList format + * + * @param comments ExceptionItem.comments + */ +export const getFormattedComments = (comments: CommentsArray): EuiCommentProps[] => { + return comments.map((commentItem) => ({ + username: commentItem.created_by, + timestamp: ( + <FormattedRelativePreferenceDate value={commentItem.created_at} dateFormat="MMM D, YYYY" /> + ), + event: COMMENT_EVENT, + timelineIcon: <CustomEuiAvatar size="s" name={commentItem.created_by} />, + children: <EuiText size="s">{commentItem.comment}</EuiText>, + })); +}; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts index dd9e90db327ee..5969cf9d043b4 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts @@ -24,6 +24,7 @@ export const mapToArtifactInfo = (_item: MaybeImmutable<AnyArtifact>): ArtifactI updated_at, updated_by, description, + comments: isTrustedApp(item) ? [] : item.comments, entries: entries as unknown as ArtifactInfo['entries'], os: isTrustedApp(item) ? item.os : getOsFromExceptionItem(item), effectScope: isTrustedApp(item) ? item.effectScope : getEffectScopeFromExceptionItem(item), diff --git a/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx b/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx index a77a2a41038d7..2b7b2e6b66884 100644 --- a/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx +++ b/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx @@ -10,6 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiFieldSearch, EuiButton } from '@elastic/e import { i18n } from '@kbn/i18n'; import { PolicySelectionItem, PoliciesSelector } from '../policies_selector'; import { ImmutableArray, PolicyData } from '../../../../common/endpoint/types'; +import { useEndpointPrivileges } from '../../../common/components/user_privileges/use_endpoint_privileges'; export interface SearchExceptionsProps { defaultValue?: string; @@ -31,6 +32,7 @@ export const SearchExceptions = memo<SearchExceptionsProps>( defaultIncludedPolicies, defaultExcludedPolicies, }) => { + const { isPlatinumPlus } = useEndpointPrivileges(); const [query, setQuery] = useState<string>(defaultValue); const [includedPolicies, setIncludedPolicies] = useState<string>(defaultIncludedPolicies || ''); const [excludedPolicies, setExcludedPolicies] = useState<string>(defaultExcludedPolicies || ''); @@ -88,7 +90,7 @@ export const SearchExceptions = memo<SearchExceptionsProps>( data-test-subj="searchField" /> </EuiFlexItem> - {hasPolicyFilter && policyList ? ( + {isPlatinumPlus && hasPolicyFilter && policyList ? ( <EuiFlexItem grow={false}> <PoliciesSelector policies={policyList} diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/event_filters/store/middleware.ts index 0c90e21b49530..c77494aad2de2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/store/middleware.ts @@ -231,8 +231,8 @@ const refreshListDataIfNeeded: MiddlewareActionHandler = async (store, eventFilt dispatch({ type: 'eventFiltersListPageDataChanged', payload: { - type: 'LoadingResourceState', // @ts-expect-error-next-line will be fixed with when AsyncResourceState is refactored (#830) + type: 'LoadingResourceState', previousState: getCurrentListPageDataState(state), }, }); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx index b974dfebd4eb1..0729f95bb44a9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx @@ -14,6 +14,7 @@ import { isFailedResourceState, isLoadedResourceState } from '../../../state'; // Needed to mock the data services used by the ExceptionItem component jest.mock('../../../../common/lib/kibana'); +jest.mock('../../../../common/components/user_privileges/use_endpoint_privileges'); describe('When on the Event Filters List Page', () => { let render: () => ReturnType<AppContextTestRender['render']>; @@ -108,19 +109,15 @@ describe('When on the Event Filters List Page', () => { it('should render expected fields on card', async () => { render(); await dataReceived(); - const eventMeta = ([] as HTMLElement[]).map.call( - renderResult.getByTestId('exceptionsViewerItemDetails').querySelectorAll('dd'), - (ele) => ele.textContent - ); - expect(eventMeta).toEqual([ - 'some name', - 'April 20th 2020 @ 11:25:31', - 'some user', - 'April 20th 2020 @ 11:25:31', - 'some user', - 'some description', - ]); + [ + ['subHeader-touchedBy-createdBy-value', 'some user'], + ['subHeader-touchedBy-updatedBy-value', 'some user'], + ['header-created-value', '4/20/2020'], + ['header-updated-value', '4/20/2020'], + ].forEach(([suffix, value]) => + expect(renderResult.getByTestId(`eventFilterCard-${suffix}`).textContent).toEqual(value) + ); }); it('should show API error if one is encountered', async () => { @@ -142,8 +139,13 @@ describe('When on the Event Filters List Page', () => { it('should show modal when delete is clicked on a card', async () => { render(); await dataReceived(); - act(() => { - fireEvent.click(renderResult.getByTestId('exceptionsViewerDeleteBtn')); + + await act(async () => { + (await renderResult.findAllByTestId('eventFilterCard-header-actions-button'))[0].click(); + }); + + await act(async () => { + (await renderResult.findByTestId('deleteEventFilterAction')).click(); }); expect( diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx index e206f85df6548..db4e5dbb531b2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx @@ -36,16 +36,20 @@ import { } from '../store/selector'; import { PaginatedContent, PaginatedContentProps } from '../../../components/paginated_content'; import { Immutable, ListPageRouteState } from '../../../../../common/endpoint/types'; +import { ExceptionItem } from '../../../../common/components/exceptions/viewer/exception_item'; import { - ExceptionItem, - ExceptionItemProps, -} from '../../../../common/components/exceptions/viewer/exception_item'; + AnyArtifact, + ArtifactEntryCard, + ArtifactEntryCardProps, +} from '../../../components/artifact_entry_card'; import { EventFilterDeleteModal } from './components/event_filter_delete_modal'; import { SearchExceptions } from '../../../components/search_exceptions'; import { BackToExternalAppButton } from '../../../components/back_to_external_app_button'; import { ABOUT_EVENT_FILTERS } from './translations'; +type ArtifactEntryCardType = typeof ArtifactEntryCard; + type EventListPaginatedContent = PaginatedContentProps< Immutable<ExceptionListItemSchema>, typeof ExceptionItem @@ -61,6 +65,20 @@ const AdministrationListPage = styled(_AdministrationListPage)` } `; +const EDIT_EVENT_FILTER_ACTION_LABEL = i18n.translate( + 'xpack.securitySolution.eventFilters.list.cardAction.edit', + { + defaultMessage: 'Edit event filter', + } +); + +const DELETE_EVENT_FILTER_ACTION_LABEL = i18n.translate( + 'xpack.securitySolution.eventFilters.list.cardAction.delete', + { + defaultMessage: 'Delete event filter', + } +); + export const EventFiltersListPage = memo(() => { const { state: routeState } = useLocation<ListPageRouteState | undefined>(); const history = useHistory(); @@ -133,41 +151,6 @@ export const EventFiltersListPage = memo(() => { [navigateCallback] ); - const handleItemEdit: ExceptionItemProps['onEditException'] = useCallback( - (item: ExceptionListItemSchema) => { - navigateCallback({ - show: 'edit', - id: item.id, - }); - }, - [navigateCallback] - ); - - const handleItemDelete: ExceptionItemProps['onDeleteException'] = useCallback( - ({ id }) => { - dispatch({ - type: 'eventFilterForDeletion', - // Casting below needed due to error around the comments array needing to be mutable - payload: listItems.find((item) => item.id === id)! as ExceptionListItemSchema, - }); - }, - [dispatch, listItems] - ); - - const handleItemComponentProps: EventListPaginatedContent['itemComponentProps'] = useCallback( - (exceptionItem) => ({ - exceptionItem: exceptionItem as ExceptionListItemSchema, - loadingItemIds: [], - commentsAccordionId: '', - onEditException: handleItemEdit, - onDeleteException: handleItemDelete, - showModified: true, - showName: true, - 'data-test-subj': `eventFilterCard`, - }), - [handleItemDelete, handleItemEdit] - ); - const handlePaginatedContentChange: EventListPaginatedContent['onChange'] = useCallback( ({ pageIndex, pageSize }) => { navigateCallback({ @@ -186,6 +169,59 @@ export const EventFiltersListPage = memo(() => { [navigateCallback, dispatch] ); + const artifactCardPropsPerItem = useMemo(() => { + const cachedCardProps: Record<string, ArtifactEntryCardProps> = {}; + + // Casting `listItems` below to remove the `Immutable<>` from it in order to prevent errors + // with common component's props + for (const eventFilter of listItems as ExceptionListItemSchema[]) { + let policies: ArtifactEntryCardProps['policies']; + + cachedCardProps[eventFilter.id] = { + item: eventFilter as AnyArtifact, + policies, + hideDescription: true, + 'data-test-subj': 'eventFilterCard', + actions: [ + { + icon: 'controlsHorizontal', + onClick: () => { + history.push( + getEventFiltersListPath({ + ...location, + show: 'edit', + id: eventFilter.id, + }) + ); + }, + 'data-test-subj': 'editEventFilterAction', + children: EDIT_EVENT_FILTER_ACTION_LABEL, + }, + { + icon: 'trash', + onClick: () => { + dispatch({ + type: 'eventFilterForDeletion', + payload: eventFilter, + }); + }, + 'data-test-subj': 'deleteEventFilterAction', + children: DELETE_EVENT_FILTER_ACTION_LABEL, + }, + ], + }; + } + + return cachedCardProps; + }, [dispatch, history, listItems, location]); + + const handleArtifactCardProps = useCallback( + (eventFilter: ExceptionListItemSchema) => { + return artifactCardPropsPerItem[eventFilter.id]; + }, + [artifactCardPropsPerItem] + ); + return ( <AdministrationListPage headerBackComponent={backButton} @@ -244,10 +280,10 @@ export const EventFiltersListPage = memo(() => { </> )} - <PaginatedContent<Immutable<ExceptionListItemSchema>, typeof ExceptionItem> + <PaginatedContent<ExceptionListItemSchema, ArtifactEntryCardType> items={listItems} - ItemComponent={ExceptionItem} - itemComponentProps={handleItemComponentProps} + ItemComponent={ArtifactEntryCard} + itemComponentProps={handleArtifactCardProps} onChange={handlePaginatedContentChange} error={fetchError?.message} loading={isLoading} diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/service.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/service.ts index 8af353a3c9531..b58c2d901c2cc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/service.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/service.ts @@ -9,6 +9,7 @@ import { CreateExceptionListItemSchema, ExceptionListItemSchema, FoundExceptionListItemSchema, + UpdateExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import { ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID } from '@kbn/securitysolution-list-constants'; import { HttpStart } from 'kibana/public'; @@ -88,3 +89,26 @@ export async function deleteHostIsolationExceptionItems(http: HttpStart, id: str }, }); } + +export async function getOneHostIsolationExceptionItem( + http: HttpStart, + id: string +): Promise<UpdateExceptionListItemSchema> { + await ensureHostIsolationExceptionsListExists(http); + return http.get<ExceptionListItemSchema>(EXCEPTION_LIST_ITEM_URL, { + query: { + id, + namespace_type: 'agnostic', + }, + }); +} + +export async function updateOneHostIsolationExceptionItem( + http: HttpStart, + exception: UpdateExceptionListItemSchema +): Promise<ExceptionListItemSchema> { + await ensureHostIsolationExceptionsListExists(http); + return http.put<ExceptionListItemSchema>(EXCEPTION_LIST_ITEM_URL, { + body: JSON.stringify(exception), + }); +} diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/action.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/action.ts index a5fae36486f98..237868ad18c50 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/action.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/action.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { + ExceptionListItemSchema, + UpdateExceptionListItemSchema, +} from '@kbn/securitysolution-io-ts-list-types'; import { Action } from 'redux'; import { HostIsolationExceptionsPageState } from '../types'; @@ -38,10 +41,24 @@ export type HostIsolationExceptionsDeleteStatusChanged = Action<'hostIsolationExceptionsDeleteStatusChanged'> & { payload: HostIsolationExceptionsPageState['deletion']['status']; }; + +export type HostIsolationExceptionsMarkToEdit = Action<'hostIsolationExceptionsMarkToEdit'> & { + payload: { + id: string; + }; +}; + +export type HostIsolationExceptionsSubmitEdit = Action<'hostIsolationExceptionsSubmitEdit'> & { + payload: UpdateExceptionListItemSchema; +}; + export type HostIsolationExceptionsPageAction = | HostIsolationExceptionsPageDataChanged | HostIsolationExceptionsCreateEntry | HostIsolationExceptionsFormStateChanged | HostIsolationExceptionsDeleteItem | HostIsolationExceptionsSubmitDelete - | HostIsolationExceptionsDeleteStatusChanged; + | HostIsolationExceptionsDeleteStatusChanged + | HostIsolationExceptionsFormEntryChanged + | HostIsolationExceptionsMarkToEdit + | HostIsolationExceptionsSubmitEdit; diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.test.ts index 266853fdab5e2..878c17a1a2757 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.test.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { + CreateExceptionListItemSchema, + UpdateEndpointListItemSchema, +} from '@kbn/securitysolution-io-ts-list-types'; import { applyMiddleware, createStore, Store } from 'redux'; import { coreMock } from '../../../../../../../../src/core/public/mocks'; import { getFoundExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/found_exception_list_item_schema.mock'; @@ -24,6 +27,8 @@ import { createHostIsolationExceptionItem, deleteHostIsolationExceptionItems, getHostIsolationExceptionItems, + getOneHostIsolationExceptionItem, + updateOneHostIsolationExceptionItem, } from '../service'; import { HostIsolationExceptionsPageState } from '../types'; import { createEmptyHostIsolationException } from '../utils'; @@ -36,6 +41,8 @@ jest.mock('../service'); const getHostIsolationExceptionItemsMock = getHostIsolationExceptionItems as jest.Mock; const deleteHostIsolationExceptionItemsMock = deleteHostIsolationExceptionItems as jest.Mock; const createHostIsolationExceptionItemMock = createHostIsolationExceptionItem as jest.Mock; +const getOneHostIsolationExceptionItemMock = getOneHostIsolationExceptionItem as jest.Mock; +const updateOneHostIsolationExceptionItemMock = updateOneHostIsolationExceptionItem as jest.Mock; const fakeCoreStart = coreMock.createStart({ basePath: '/mock' }); @@ -170,6 +177,7 @@ describe('Host isolation exceptions middleware', () => { ], }; }); + it('should dispatch a form loading state when an entry is submited', async () => { const waiter = spyMiddleware.waitForAction('hostIsolationExceptionsFormStateChanged', { validate({ payload }) { @@ -182,6 +190,7 @@ describe('Host isolation exceptions middleware', () => { }); await waiter; }); + it('should dispatch a form success state when an entry is confirmed by the API', async () => { const waiter = spyMiddleware.waitForAction('hostIsolationExceptionsFormStateChanged', { validate({ payload }) { @@ -198,6 +207,7 @@ describe('Host isolation exceptions middleware', () => { exception: entry, }); }); + it('should dispatch a form failure state when an entry is rejected by the API', async () => { createHostIsolationExceptionItemMock.mockRejectedValue({ body: { message: 'error message', statusCode: 500, error: 'Not today' }, @@ -215,6 +225,101 @@ describe('Host isolation exceptions middleware', () => { }); }); + describe('When updating an item from host isolation exceptions', () => { + const fakeId = 'dc5d1d00-2766-11ec-981f-7f84cfc8764f'; + let fakeException: UpdateEndpointListItemSchema; + beforeEach(() => { + fakeException = { + ...createEmptyHostIsolationException(), + name: 'name edit me', + description: 'initial description', + id: fakeId, + item_id: fakeId, + entries: [ + { + field: 'destination.ip', + operator: 'included', + type: 'match', + value: '10.0.0.5', + }, + ], + }; + getOneHostIsolationExceptionItemMock.mockReset(); + getOneHostIsolationExceptionItemMock.mockImplementation(async () => { + return fakeException; + }); + }); + + it('should load data from an entry when an exception is marked to edit', async () => { + const waiter = spyMiddleware.waitForAction('hostIsolationExceptionsFormEntryChanged'); + store.dispatch({ + type: 'hostIsolationExceptionsMarkToEdit', + payload: { + id: fakeId, + }, + }); + await waiter; + expect(getOneHostIsolationExceptionItemMock).toHaveBeenCalledWith(fakeCoreStart.http, fakeId); + }); + + it('should call the update API when an item edit is submitted', async () => { + const waiter = Promise.all([ + // loading status + spyMiddleware.waitForAction('hostIsolationExceptionsFormStateChanged', { + validate: ({ payload }) => { + return isLoadingResourceState(payload); + }, + }), + // loaded status + spyMiddleware.waitForAction('hostIsolationExceptionsFormStateChanged', { + validate({ payload }) { + return isLoadedResourceState(payload); + }, + }), + ]); + store.dispatch({ + type: 'hostIsolationExceptionsSubmitEdit', + payload: fakeException, + }); + expect(updateOneHostIsolationExceptionItemMock).toHaveBeenCalledWith(fakeCoreStart.http, { + name: 'name edit me', + description: 'initial description', + id: fakeId, + item_id: fakeId, + entries: [ + { + field: 'destination.ip', + operator: 'included', + type: 'match', + value: '10.0.0.5', + }, + ], + namespace_type: 'agnostic', + os_types: ['windows', 'linux', 'macos'], + tags: ['policy:all'], + type: 'simple', + comments: [], + }); + await waiter; + }); + + it('should dispatch a form failure state when an entry is rejected by the API', async () => { + updateOneHostIsolationExceptionItemMock.mockRejectedValue({ + body: { message: 'error message', statusCode: 500, error: 'Not today' }, + }); + const waiter = spyMiddleware.waitForAction('hostIsolationExceptionsFormStateChanged', { + validate({ payload }) { + return isFailedResourceState(payload); + }, + }); + store.dispatch({ + type: 'hostIsolationExceptionsSubmitEdit', + payload: fakeException, + }); + await waiter; + }); + }); + describe('When deleting an item from host isolation exceptions', () => { beforeEach(() => { deleteHostIsolationExceptionItemsMock.mockReset(); diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.ts index bbc754e8155b0..2587fff5bfafd 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/middleware.ts @@ -9,11 +9,12 @@ import { CreateExceptionListItemSchema, ExceptionListItemSchema, FoundExceptionListItemSchema, + UpdateExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import { CoreStart, HttpSetup, HttpStart } from 'kibana/public'; import { matchPath } from 'react-router-dom'; -import { transformNewItemOutput } from '@kbn/securitysolution-list-hooks'; -import { AppLocation, Immutable } from '../../../../../common/endpoint/types'; +import { transformNewItemOutput, transformOutput } from '@kbn/securitysolution-list-hooks'; +import { AppLocation, Immutable, ImmutableObject } from '../../../../../common/endpoint/types'; import { ImmutableMiddleware, ImmutableMiddlewareAPI } from '../../../../common/store'; import { AppAction } from '../../../../common/store/actions'; import { MANAGEMENT_ROUTING_HOST_ISOLATION_EXCEPTIONS_PATH } from '../../../common/constants'; @@ -21,11 +22,14 @@ import { parseQueryFilterToKQL } from '../../../common/utils'; import { createFailedResourceState, createLoadedResourceState, + createLoadingResourceState, } from '../../../state/async_resource_builders'; import { deleteHostIsolationExceptionItems, getHostIsolationExceptionItems, createHostIsolationExceptionItem, + getOneHostIsolationExceptionItem, + updateOneHostIsolationExceptionItem, } from '../service'; import { HostIsolationExceptionsPageState } from '../types'; import { getCurrentListPageDataState, getCurrentLocation, getItemToDelete } from './selector'; @@ -53,6 +57,14 @@ export const createHostIsolationExceptionsPageMiddleware = ( if (action.type === 'hostIsolationExceptionsSubmitDelete') { deleteHostIsolationExceptionsItem(store, coreStart.http); } + + if (action.type === 'hostIsolationExceptionsMarkToEdit') { + loadHostIsolationExceptionsItem(store, coreStart.http, action.payload.id); + } + + if (action.type === 'hostIsolationExceptionsSubmitEdit') { + updateHostIsolationExceptionsItem(store, coreStart.http, action.payload); + } }; }; @@ -67,8 +79,8 @@ async function createHostIsolationException( dispatch({ type: 'hostIsolationExceptionsFormStateChanged', payload: { - type: 'LoadingResourceState', // @ts-expect-error-next-line will be fixed with when AsyncResourceState is refactored (#830) + type: 'LoadingResourceState', previousState: entry, }, }); @@ -110,8 +122,8 @@ async function loadHostIsolationExceptionsList( dispatch({ type: 'hostIsolationExceptionsPageDataChanged', payload: { - type: 'LoadingResourceState', // @ts-expect-error-next-line will be fixed with when AsyncResourceState is refactored (#830) + type: 'LoadingResourceState', previousState: getCurrentListPageDataState(store.getState()), }, }); @@ -152,8 +164,8 @@ async function deleteHostIsolationExceptionsItem( dispatch({ type: 'hostIsolationExceptionsDeleteStatusChanged', payload: { - type: 'LoadingResourceState', // @ts-expect-error-next-line will be fixed with when AsyncResourceState is refactored (#830) + type: 'LoadingResourceState', previousState: store.getState().deletion.status, }, }); @@ -172,3 +184,69 @@ async function deleteHostIsolationExceptionsItem( }); } } + +async function loadHostIsolationExceptionsItem( + store: ImmutableMiddlewareAPI<HostIsolationExceptionsPageState, AppAction>, + http: HttpSetup, + id: string +) { + const { dispatch } = store; + try { + const exception: UpdateExceptionListItemSchema = await getOneHostIsolationExceptionItem( + http, + id + ); + dispatch({ + type: 'hostIsolationExceptionsFormEntryChanged', + payload: exception, + }); + } catch (error) { + dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: createFailedResourceState<ExceptionListItemSchema>(error.body ?? error), + }); + } +} +async function updateHostIsolationExceptionsItem( + store: ImmutableMiddlewareAPI<HostIsolationExceptionsPageState, AppAction>, + http: HttpSetup, + exception: ImmutableObject<UpdateExceptionListItemSchema> +) { + const { dispatch } = store; + dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: createLoadingResourceState(createLoadedResourceState(exception)), + }); + + try { + const entry = transformOutput(exception as UpdateExceptionListItemSchema); + // Clean unnecessary fields for update action + const fieldsToRemove: Array<keyof ExceptionListItemSchema> = [ + 'created_at', + 'created_by', + 'created_at', + 'created_by', + 'list_id', + 'tie_breaker_id', + 'updated_at', + 'updated_by', + ]; + + fieldsToRemove.forEach((field) => { + delete entry[field as keyof UpdateExceptionListItemSchema]; + }); + const response: ExceptionListItemSchema = await updateOneHostIsolationExceptionItem( + http, + entry + ); + dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: createLoadedResourceState(response), + }); + } catch (error) { + dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: createFailedResourceState<ExceptionListItemSchema>(error.body ?? error), + }); + } +} diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/reducer.ts index d97295598f445..77a1c248d0cf0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/reducer.ts @@ -56,6 +56,15 @@ export const hostIsolationExceptionsPageReducer: StateReducer = ( }, }; } + case 'hostIsolationExceptionsFormEntryChanged': { + return { + ...state, + form: { + ...state.form, + entry: action.payload, + }, + }; + } case 'hostIsolationExceptionsPageDataChanged': { return { ...state, diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/selector.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/selector.ts index 4462864e90702..3eca524d830d5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/selector.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/store/selector.ts @@ -9,6 +9,7 @@ import { Pagination } from '@elastic/eui'; import { ExceptionListItemSchema, FoundExceptionListItemSchema, + UpdateExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import { createSelector } from 'reselect'; import { Immutable } from '../../../../../common/endpoint/types'; @@ -108,3 +109,18 @@ export const getDeleteError: HostIsolationExceptionsSelector<ServerApiError | un return status.error; } }); + +const getFormState: HostIsolationExceptionsSelector<StoreState['form']> = (state) => { + return state.form; +}; + +export const getFormStatusFailure: HostIsolationExceptionsSelector<ServerApiError | undefined> = + createSelector(getFormState, (form) => { + if (isFailedResourceState(form.status)) { + return form.status.error; + } + }); + +export const getExceptionToEdit: HostIsolationExceptionsSelector< + UpdateExceptionListItemSchema | undefined +> = (state) => (state.form.entry ? (state.form.entry as UpdateExceptionListItemSchema) : undefined); diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/types.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/types.ts index 1a74042fb652e..2e61a39eb7542 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/types.ts @@ -9,6 +9,7 @@ import type { CreateExceptionListItemSchema, ExceptionListItemSchema, FoundExceptionListItemSchema, + UpdateExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import { AsyncResourceState } from '../../state/async_resource_state'; @@ -29,7 +30,7 @@ export interface HostIsolationExceptionsPageState { status: AsyncResourceState<ExceptionListItemSchema>; }; form: { - entry?: CreateExceptionListItemSchema; - status: AsyncResourceState<ExceptionListItemSchema>; + entry?: CreateExceptionListItemSchema | UpdateExceptionListItemSchema; + status: AsyncResourceState<CreateExceptionListItemSchema | UpdateExceptionListItemSchema>; }; } diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx index 0b09b4bfa14c4..2a75ab0622128 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx @@ -83,7 +83,7 @@ describe('When on the host isolation exceptions delete modal', () => { act(() => { fireEvent.click(cancelButton); }); - await waiter; + expect(await waiter).toBeTruthy(); }); it('should show success toast after the delete is completed', async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx index b06449de69d8c..826f7bf6c4d8a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx @@ -12,12 +12,16 @@ import { AppContextTestRender, createAppRootMockRenderer, } from '../../../../../common/mock/endpoint'; -import { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { + CreateExceptionListItemSchema, + UpdateExceptionListItemSchema, +} from '@kbn/securitysolution-io-ts-list-types'; import userEvent from '@testing-library/user-event'; +import uuid from 'uuid'; describe('When on the host isolation exceptions add entry form', () => { let render: ( - exception: CreateExceptionListItemSchema + exception: CreateExceptionListItemSchema | UpdateExceptionListItemSchema ) => ReturnType<AppContextTestRender['render']>; let renderResult: ReturnType<typeof render>; const onChange = jest.fn(); @@ -27,7 +31,7 @@ describe('When on the host isolation exceptions add entry form', () => { onChange.mockReset(); onError.mockReset(); const mockedContext = createAppRootMockRenderer(); - render = (exception: CreateExceptionListItemSchema) => { + render = (exception) => { return mockedContext.render( <HostIsolationExceptionsForm exception={exception} onChange={onChange} onError={onError} /> ); @@ -72,4 +76,47 @@ describe('When on the host isolation exceptions add entry form', () => { }); }); }); + describe('When editing an existing exception', () => { + let existingException: UpdateExceptionListItemSchema; + beforeEach(() => { + existingException = { + ...createEmptyHostIsolationException(), + name: 'name edit me', + description: 'initial description', + id: uuid.v4(), + item_id: uuid.v4(), + entries: [ + { + field: 'destination.ip', + operator: 'included', + type: 'match', + value: '10.0.0.1', + }, + ], + }; + renderResult = render(existingException); + }); + it('should render the form with pre-filled inputs', () => { + expect(renderResult.getByTestId('hostIsolationExceptions-form-name-input')).toHaveValue( + 'name edit me' + ); + expect(renderResult.getByTestId('hostIsolationExceptions-form-ip-input')).toHaveValue( + '10.0.0.1' + ); + expect( + renderResult.getByTestId('hostIsolationExceptions-form-description-input') + ).toHaveValue('initial description'); + }); + it('should call onChange when a value is introduced in a field', () => { + const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); + userEvent.clear(ipInput); + userEvent.type(ipInput, '10.0.100.1'); + expect(onChange).toHaveBeenCalledWith({ + ...existingException, + entries: [ + { field: 'destination.ip', operator: 'included', type: 'match', value: '10.0.100.1' }, + ], + }); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.tsx index 84263f9d07c81..7b13df16da483 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.tsx @@ -16,7 +16,10 @@ import { EuiTitle, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { + CreateExceptionListItemSchema, + UpdateExceptionListItemSchema, +} from '@kbn/securitysolution-io-ts-list-types'; import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { isValidIPv4OrCIDR } from '../../utils'; import { @@ -34,18 +37,19 @@ interface ExceptionIpEntry { field: 'destination.ip'; operator: 'included'; type: 'match'; - value: ''; + value: string; } export const HostIsolationExceptionsForm: React.FC<{ - exception: CreateExceptionListItemSchema; + exception: CreateExceptionListItemSchema | UpdateExceptionListItemSchema; onError: (error: boolean) => void; - onChange: (exception: CreateExceptionListItemSchema) => void; + onChange: (exception: CreateExceptionListItemSchema | UpdateExceptionListItemSchema) => void; }> = memo(({ exception, onError, onChange }) => { + const ipEntry = exception.entries[0] as ExceptionIpEntry; const [hasBeenInputNameVisited, setHasBeenInputNameVisited] = useState(false); const [hasBeenInputIpVisited, setHasBeenInputIpVisited] = useState(false); - const [hasNameError, setHasNameError] = useState(true); - const [hasIpError, setHasIpError] = useState(true); + const [hasNameError, setHasNameError] = useState(!exception.name); + const [hasIpError, setHasIpError] = useState(!ipEntry.value); useEffect(() => { onError(hasNameError || hasIpError); diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.test.tsx index 6cfc9f56beadf..4ab4ed785e491 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.test.tsx @@ -14,6 +14,8 @@ import userEvent from '@testing-library/user-event'; import { HostIsolationExceptionsFormFlyout } from './form_flyout'; import { act } from 'react-dom/test-utils'; import { HOST_ISOLATION_EXCEPTIONS_PATH } from '../../../../../../common/constants'; +import uuid from 'uuid'; +import { createEmptyHostIsolationException } from '../../utils'; jest.mock('../../service.ts'); @@ -23,8 +25,6 @@ describe('When on the host isolation exceptions flyout form', () => { let renderResult: ReturnType<typeof render>; let waitForAction: AppContextTestRender['middlewareSpy']['waitForAction']; - // const createHostIsolationExceptionItemMock = createHostIsolationExceptionItem as jest.mock; - beforeEach(() => { mockedContext = createAppRootMockRenderer(); render = () => { @@ -34,7 +34,11 @@ describe('When on the host isolation exceptions flyout form', () => { }); describe('When creating a new exception', () => { - describe('with invalid data', () => { + beforeEach(() => { + mockedContext.history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=create`); + }); + + describe('with invalida data', () => { it('should show disabled buttons when the form first load', () => { renderResult = render(); expect(renderResult.getByTestId('add-exception-cancel-button')).not.toHaveAttribute( @@ -45,6 +49,7 @@ describe('When on the host isolation exceptions flyout form', () => { ); }); }); + describe('with valid data', () => { beforeEach(() => { renderResult = render(); @@ -53,6 +58,7 @@ describe('When on the host isolation exceptions flyout form', () => { userEvent.type(nameInput, 'test name'); userEvent.type(ipInput, '10.0.0.1'); }); + it('should show enable buttons when the form is valid', () => { expect(renderResult.getByTestId('add-exception-cancel-button')).not.toHaveAttribute( 'disabled' @@ -61,13 +67,15 @@ describe('When on the host isolation exceptions flyout form', () => { 'disabled' ); }); + it('should submit the entry data when submit is pressed with valid data', async () => { const confirmButton = renderResult.getByTestId('add-exception-confirm-button'); expect(confirmButton).not.toHaveAttribute('disabled'); const waiter = waitForAction('hostIsolationExceptionsCreateEntry'); userEvent.click(confirmButton); - await waiter; + expect(await waiter).toBeTruthy(); }); + it('should disable the submit button when an operation is in progress', () => { act(() => { mockedContext.store.dispatch({ @@ -81,6 +89,7 @@ describe('When on the host isolation exceptions flyout form', () => { const confirmButton = renderResult.getByTestId('add-exception-confirm-button'); expect(confirmButton).toHaveAttribute('disabled'); }); + it('should show a toast and close the flyout when the operation is finished', () => { mockedContext.history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=create`); act(() => { @@ -95,13 +104,14 @@ describe('When on the host isolation exceptions flyout form', () => { expect(mockedContext.coreStart.notifications.toasts.addSuccess).toHaveBeenCalled(); expect(mockedContext.history.location.search).toBe(''); }); - it('should show an error toast operation fails and enable the submit button', () => { + + it('should show an error toast if operation fails and enable the submit button', async () => { act(() => { mockedContext.store.dispatch({ type: 'hostIsolationExceptionsFormStateChanged', payload: { type: 'FailedResourceState', - previousState: { type: 'UninitialisedResourceState' }, + error: new Error('mocked error'), }, }); }); @@ -111,4 +121,99 @@ describe('When on the host isolation exceptions flyout form', () => { }); }); }); + describe('When editing an existing exception', () => { + const fakeId = 'dc5d1d00-2766-11ec-981f-7f84cfc8764f'; + beforeEach(() => { + mockedContext.history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=edit&id=${fakeId}`); + }); + + describe('without loaded data', () => { + it('should show a loading status while the item is loaded', () => { + renderResult = render(); + expect(renderResult.getByTestId('loading-spinner')).toBeTruthy(); + }); + + it('should request to load data about the editing exception', async () => { + const waiter = waitForAction('hostIsolationExceptionsMarkToEdit', { + validate: ({ payload }) => { + return payload.id === fakeId; + }, + }); + renderResult = render(); + expect(await waiter).toBeTruthy(); + }); + + it('should show a warning toast if the item fails to load', () => { + renderResult = render(); + act(() => { + mockedContext.store.dispatch({ + type: 'hostIsolationExceptionsFormEntryChanged', + payload: undefined, + }); + + mockedContext.store.dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: { + type: 'FailedResourceState', + error: new Error('mocked error'), + }, + }); + }); + expect(mockedContext.coreStart.notifications.toasts.addWarning).toHaveBeenCalled(); + }); + }); + + describe('with loaded data', () => { + beforeEach(async () => { + mockedContext.store.dispatch({ + type: 'hostIsolationExceptionsFormEntryChanged', + payload: { + ...createEmptyHostIsolationException(), + name: 'name edit me', + description: 'initial description', + id: fakeId, + item_id: uuid.v4(), + entries: [ + { + field: 'destination.ip', + operator: 'included', + type: 'match', + value: '10.0.0.5', + }, + ], + }, + }); + renderResult = render(); + }); + + it('should request data again if the url id is changed', async () => { + const otherId = 'd75fbd74-2a92-11ec-8d3d-0242ac130003'; + act(() => { + mockedContext.history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=edit&id=${otherId}`); + }); + await waitForAction('hostIsolationExceptionsMarkToEdit', { + validate: ({ payload }) => { + return payload.id === otherId; + }, + }); + }); + + it('should enable the buttons from the start', () => { + expect(renderResult.getByTestId('add-exception-cancel-button')).not.toHaveAttribute( + 'disabled' + ); + expect(renderResult.getByTestId('add-exception-confirm-button')).not.toHaveAttribute( + 'disabled' + ); + }); + + it('should submit the entry data when submit is pressed with valid data', async () => { + const confirmButton = renderResult.getByTestId('add-exception-confirm-button'); + expect(confirmButton).not.toHaveAttribute('disabled'); + const waiter = waitForAction('hostIsolationExceptionsSubmitEdit'); + userEvent.click(confirmButton); + expect(await waiter).toBeTruthy(); + }); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx index 5502a1b8ea2b1..de12616c67a3c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx @@ -16,20 +16,32 @@ import { EuiFlyoutHeader, EuiTitle, } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { + CreateExceptionListItemSchema, + UpdateExceptionListItemSchema, +} from '@kbn/securitysolution-io-ts-list-types'; +import { omit } from 'lodash'; import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; import { Dispatch } from 'redux'; import { Loader } from '../../../../../common/components/loader'; import { useToasts } from '../../../../../common/lib/kibana'; +import { getHostIsolationExceptionsListPath } from '../../../../common/routing'; import { - isFailedResourceState, isLoadedResourceState, isLoadingResourceState, } from '../../../../state/async_resource_state'; +import { + getCreateErrorMessage, + getCreationSuccessMessage, + getLoadErrorMessage, + getUpdateErrorMessage, + getUpdateSuccessMessage, +} from './translations'; import { HostIsolationExceptionsPageAction } from '../../store/action'; +import { getCurrentLocation, getExceptionToEdit, getFormStatusFailure } from '../../store/selector'; import { createEmptyHostIsolationException } from '../../utils'; import { useHostIsolationExceptionsNavigateCallback, @@ -41,20 +53,26 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => { const dispatch = useDispatch<Dispatch<HostIsolationExceptionsPageAction>>(); const toasts = useToasts(); + const location = useHostIsolationExceptionsSelector(getCurrentLocation); + const creationInProgress = useHostIsolationExceptionsSelector((state) => isLoadingResourceState(state.form.status) ); const creationSuccessful = useHostIsolationExceptionsSelector((state) => isLoadedResourceState(state.form.status) ); - const creationFailure = useHostIsolationExceptionsSelector((state) => - isFailedResourceState(state.form.status) - ); + const creationFailure = useHostIsolationExceptionsSelector(getFormStatusFailure); + + const exceptionToEdit = useHostIsolationExceptionsSelector(getExceptionToEdit); const navigateCallback = useHostIsolationExceptionsNavigateCallback(); + const history = useHistory(); + const [formHasError, setFormHasError] = useState(true); - const [exception, setException] = useState<CreateExceptionListItemSchema | undefined>(undefined); + const [exception, setException] = useState< + CreateExceptionListItemSchema | UpdateExceptionListItemSchema | undefined + >(undefined); const onCancel = useCallback( () => @@ -65,12 +83,31 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => { [navigateCallback] ); + // load data to edit or create useEffect(() => { - setException(createEmptyHostIsolationException()); - }, []); + if (location.show === 'create' && exception === undefined) { + setException(createEmptyHostIsolationException()); + } else if (location.show === 'edit') { + // prevent flyout to show edit without an id + if (!location.id) { + onCancel(); + return; + } + // load the exception to edit + if (!exceptionToEdit || location.id !== exceptionToEdit.id) { + dispatch({ + type: 'hostIsolationExceptionsMarkToEdit', + payload: { id: location.id! }, + }); + } else { + setException(exceptionToEdit); + } + } + }, [dispatch, exception, exceptionToEdit, location.id, location.show, onCancel]); + // handle creation and edit success useEffect(() => { - if (creationSuccessful) { + if (creationSuccessful && exception?.name) { onCancel(); dispatch({ type: 'hostIsolationExceptionsFormStateChanged', @@ -78,30 +115,45 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => { type: 'UninitialisedResourceState', }, }); - toasts.addSuccess( - i18n.translate( - 'xpack.securitySolution.hostIsolationExceptions.form.creationSuccessToastTitle', - { - defaultMessage: '"{name}" has been added to the host isolation exceptions list.', - values: { name: exception?.name }, - } - ) - ); + if (exception?.item_id) { + toasts.addSuccess(getUpdateSuccessMessage(exception.name)); + } else { + toasts.addSuccess(getCreationSuccessMessage(exception.name)); + } + } + }, [creationSuccessful, dispatch, exception?.item_id, exception?.name, onCancel, toasts]); + + // handle load item to edit error + useEffect(() => { + if (creationFailure && location.show === 'edit' && !exception?.item_id) { + toasts.addWarning(getLoadErrorMessage(creationFailure)); + history.replace(getHostIsolationExceptionsListPath(omit(location, ['show', 'id']))); + dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: { + type: 'UninitialisedResourceState', + }, + }); } - }, [creationSuccessful, onCancel, dispatch, toasts, exception?.name]); + }, [creationFailure, dispatch, exception?.item_id, history, location, toasts]); + // handle edit or creation error useEffect(() => { if (creationFailure) { - toasts.addDanger( - i18n.translate( - 'xpack.securitySolution.hostIsolationExceptions.form.creationFailureToastTitle', - { - defaultMessage: 'There was an error creating the exception', - } - ) - ); + // failed to load the entry + if (exception?.item_id) { + toasts.addDanger(getUpdateErrorMessage(creationFailure)); + } else { + toasts.addDanger(getCreateErrorMessage(creationFailure)); + } + dispatch({ + type: 'hostIsolationExceptionsFormStateChanged', + payload: { + type: 'UninitialisedResourceState', + }, + }); } - }, [dispatch, toasts, creationFailure]); + }, [creationFailure, dispatch, exception?.item_id, toasts]); const handleOnCancel = useCallback(() => { if (creationInProgress) return; @@ -109,10 +161,17 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => { }, [creationInProgress, onCancel]); const handleOnSubmit = useCallback(() => { - dispatch({ - type: 'hostIsolationExceptionsCreateEntry', - payload: exception, - }); + if (exception?.item_id) { + dispatch({ + type: 'hostIsolationExceptionsSubmitEdit', + payload: exception, + }); + } else { + dispatch({ + type: 'hostIsolationExceptionsCreateEntry', + payload: exception, + }); + } }, [dispatch, exception]); const confirmButtonMemo = useMemo( @@ -124,13 +183,20 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => { onClick={handleOnSubmit} isLoading={creationInProgress} > - <FormattedMessage - id="xpack.securitySolution.hostIsolationExceptions.flyout.actions.create" - defaultMessage="Add Host Isolation Exception" - /> + {exception?.item_id ? ( + <FormattedMessage + id="xpack.securitySolution.hostIsolationExceptions.flyout.editButton" + defaultMessage="Edit Host Isolation Exception" + /> + ) : ( + <FormattedMessage + id="xpack.securitySolution.hostIsolationExceptions.flyout.createButton" + defaultMessage="Add Host Isolation Exception" + /> + )} </EuiButton> ), - [formHasError, creationInProgress, handleOnSubmit] + [formHasError, creationInProgress, handleOnSubmit, exception?.item_id] ); return exception ? ( @@ -141,12 +207,21 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => { > <EuiFlyoutHeader hasBorder> <EuiTitle size="m"> - <h2> - <FormattedMessage - id="xpack.securitySolution.hostIsolationExceptions.flyout.title" - defaultMessage="Add Host Isolation Exception" - /> - </h2> + {exception?.item_id ? ( + <h2> + <FormattedMessage + id="xpack.securitySolution.hostIsolationExceptions.flyout.editTitle" + defaultMessage="Edit Host Isolation Exception" + /> + </h2> + ) : ( + <h2> + <FormattedMessage + id="xpack.securitySolution.hostIsolationExceptions.flyout.title" + defaultMessage="Add Host Isolation Exception" + /> + </h2> + )} </EuiTitle> </EuiFlyoutHeader> diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/translations.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/translations.ts index df179c7a2221c..207e094453d90 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/translations.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/translations.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { ServerApiError } from '../../../../../common/types'; export const NAME_PLACEHOLDER = i18n.translate( 'xpack.securitySolution.hostIsolationExceptions.form.name.placeholder', @@ -62,3 +63,67 @@ export const IP_ERROR = i18n.translate( defaultMessage: 'The ip is invalid. Only IPv4 with optional CIDR is supported', } ); + +export const DELETE_HOST_ISOLATION_EXCEPTION_LABEL = i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.list.action.delete', + { + defaultMessage: 'Delete Exception', + } +); + +export const EDIT_HOST_ISOLATION_EXCEPTION_LABEL = i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.list.action.edit', + { + defaultMessage: 'Edit Exception', + } +); + +export const getCreateErrorMessage = (creationError: ServerApiError) => { + return i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.form.failedToastTitle.create', + { + defaultMessage: 'There was an error creating the exception: "{error}"', + values: { error: creationError.message }, + } + ); +}; + +export const getUpdateErrorMessage = (updateError: ServerApiError) => { + return i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.form.failedToastTitle.update', + { + defaultMessage: 'There was an error updating the exception: "{error}"', + values: { error: updateError.message }, + } + ); +}; + +export const getLoadErrorMessage = (getError: ServerApiError) => { + return i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.form.failedToastTitle.get', + { + defaultMessage: 'Unable to edit exception: "{error}"', + values: { error: getError.message }, + } + ); +}; + +export const getUpdateSuccessMessage = (name: string) => { + return i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.form.editingSuccessToastTitle', + { + defaultMessage: '"{name}" has been updated.', + values: { name }, + } + ); +}; + +export const getCreationSuccessMessage = (name: string) => { + return i18n.translate( + 'xpack.securitySolution.hostIsolationExceptions.form.creationSuccessToastTitle', + { + defaultMessage: '"{name}" has been added to the host isolation exceptions list.', + values: { name }, + } + ); +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.test.tsx index ac472fdae4d7b..9de3d83ed8bab 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.test.tsx @@ -15,6 +15,7 @@ import { isFailedResourceState, isLoadedResourceState } from '../../../state'; import { getHostIsolationExceptionItems } from '../service'; import { HostIsolationExceptionsList } from './host_isolation_exceptions_list'; +jest.mock('../../../../common/components/user_privileges/use_endpoint_privileges'); jest.mock('../service'); const getHostIsolationExceptionItemsMock = getHostIsolationExceptionItems as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.tsx index cfb0121396e24..3c634a917c0ce 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/host_isolation_exceptions_list.tsx @@ -33,19 +33,16 @@ import { HostIsolationExceptionsEmptyState } from './components/empty'; import { HostIsolationExceptionsPageAction } from '../store/action'; import { HostIsolationExceptionDeleteModal } from './components/delete_modal'; import { HostIsolationExceptionsFormFlyout } from './components/form_flyout'; +import { + DELETE_HOST_ISOLATION_EXCEPTION_LABEL, + EDIT_HOST_ISOLATION_EXCEPTION_LABEL, +} from './components/translations'; type HostIsolationExceptionPaginatedContent = PaginatedContentProps< Immutable<ExceptionListItemSchema>, typeof ExceptionItem >; -const DELETE_HOST_ISOLATION_EXCEPTION_LABEL = i18n.translate( - 'xpack.securitySolution.hostIsolationExceptions.list.actions.delete', - { - defaultMessage: 'Delete Exception', - } -); - export const HostIsolationExceptionsList = () => { const listItems = useHostIsolationExceptionsSelector(getListItems); const pagination = useHostIsolationExceptionsSelector(getListPagination); @@ -70,6 +67,17 @@ export const HostIsolationExceptionsList = () => { item: element, 'data-test-subj': `hostIsolationExceptionsCard`, actions: [ + { + icon: 'trash', + onClick: () => { + navigateCallback({ + show: 'edit', + id: element.id, + }); + }, + 'data-test-subj': 'editHostIsolationException', + children: EDIT_HOST_ISOLATION_EXCEPTION_LABEL, + }, { icon: 'trash', onClick: () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts b/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts index c9a972ce29e4c..8f1530c3632dc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts @@ -52,9 +52,10 @@ export const fleetGetEndpointPackagePolicyHttpMock = path: PACKAGE_POLICY_API_ROUTES.INFO_PATTERN, method: 'get', handler: () => { - return { - items: new EndpointDocGenerator('seed').generatePolicyPackagePolicy(), + const response: GetPolicyResponse = { + item: new EndpointDocGenerator('seed').generatePolicyPackagePolicy(), }; + return response; }, }, ]); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/action/policy_trusted_apps_action.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/action/policy_trusted_apps_action.ts index 479452968df7a..b3bdfe32ef091 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/action/policy_trusted_apps_action.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/action/policy_trusted_apps_action.ts @@ -8,8 +8,10 @@ import { Action } from 'redux'; import { AsyncResourceState } from '../../../../../state'; import { - PostTrustedAppCreateResponse, + PutTrustedAppUpdateResponse, GetTrustedAppsListResponse, + TrustedApp, + MaybeImmutable, } from '../../../../../../../common/endpoint/types'; import { PolicyArtifactsState } from '../../../types'; @@ -21,13 +23,14 @@ export interface PolicyArtifactsAssignableListPageDataChanged { export interface PolicyArtifactsUpdateTrustedApps { type: 'policyArtifactsUpdateTrustedApps'; payload: { - trustedAppIds: string[]; + action: 'assign' | 'remove'; + artifacts: MaybeImmutable<TrustedApp[]>; }; } export interface PolicyArtifactsUpdateTrustedAppsChanged { type: 'policyArtifactsUpdateTrustedAppsChanged'; - payload: AsyncResourceState<PostTrustedAppCreateResponse[]>; + payload: AsyncResourceState<PutTrustedAppUpdateResponse[]>; } export interface PolicyArtifactsAssignableListExistDataChanged { @@ -58,6 +61,13 @@ export interface PolicyDetailsListOfAllPoliciesStateChanged export type PolicyDetailsTrustedAppsForceListDataRefresh = Action<'policyDetailsTrustedAppsForceListDataRefresh'>; +export type PolicyDetailsArtifactsResetRemove = Action<'policyDetailsArtifactsResetRemove'>; + +export interface PolicyDetailsTrustedAppsRemoveListStateChanged + extends Action<'policyDetailsTrustedAppsRemoveListStateChanged'> { + payload: PolicyArtifactsState['removeList']; +} + /** * All of the possible actions for Trusted Apps under the Policy Details store */ @@ -70,4 +80,6 @@ export type PolicyTrustedAppsAction = | PolicyArtifactsDeosAnyTrustedAppExists | AssignedTrustedAppsListStateChanged | PolicyDetailsListOfAllPoliciesStateChanged - | PolicyDetailsTrustedAppsForceListDataRefresh; + | PolicyDetailsTrustedAppsForceListDataRefresh + | PolicyDetailsTrustedAppsRemoveListStateChanged + | PolicyDetailsArtifactsResetRemove; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/middleware/policy_trusted_apps_middleware.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/middleware/policy_trusted_apps_middleware.ts index 360fe9fb99b8d..f50eb342acba1 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/middleware/policy_trusted_apps_middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/middleware/policy_trusted_apps_middleware.ts @@ -5,43 +5,44 @@ * 2.0. */ -import pMap from 'p-map'; -import { find, isEmpty } from 'lodash/fp'; +import { isEmpty } from 'lodash/fp'; import { - PolicyDetailsState, - MiddlewareRunner, GetPolicyListResponse, + MiddlewareRunner, MiddlewareRunnerContext, PolicyAssignedTrustedApps, + PolicyDetailsState, PolicyDetailsStore, + PolicyRemoveTrustedApps, } from '../../../types'; import { - policyIdFromParams, - getAssignableArtifactsList, doesPolicyTrustedAppsListNeedUpdate, + getCurrentArtifactsLocation, getCurrentPolicyAssignedTrustedAppsState, + getCurrentTrustedAppsRemoveListState, + getCurrentUrlLocationPaginationParams, getLatestLoadedPolicyAssignedTrustedAppsState, + getTrustedAppsIsRemoving, getTrustedAppsPolicyListState, - isPolicyTrustedAppListLoading, - getCurrentArtifactsLocation, isOnPolicyTrustedAppsView, - getCurrentUrlLocationPaginationParams, + isPolicyTrustedAppListLoading, + licensedPolicy, + policyIdFromParams, getDoesAnyTrustedAppExistsIsLoading, } from '../selectors'; import { - ImmutableArray, - ImmutableObject, - PostTrustedAppCreateRequest, - TrustedApp, Immutable, + MaybeImmutable, + PutTrustedAppUpdateResponse, + TrustedApp, } from '../../../../../../../common/endpoint/types'; import { ImmutableMiddlewareAPI } from '../../../../../../common/store'; import { TrustedAppsService } from '../../../../trusted_apps/service'; import { + createFailedResourceState, createLoadedResourceState, createLoadingResourceState, createUninitialisedResourceState, - createFailedResourceState, isLoadingResourceState, isUninitialisedResourceState, } from '../../../../../state'; @@ -83,8 +84,13 @@ export const policyTrustedAppsMiddlewareRunner: MiddlewareRunner = async ( break; case 'policyArtifactsUpdateTrustedApps': - if (getCurrentArtifactsLocation(state).show === 'list') { - await updateTrustedApps(store, trustedAppsService, action.payload.trustedAppIds); + if ( + getCurrentArtifactsLocation(state).show === 'list' && + action.payload.action === 'assign' + ) { + await updateTrustedApps(store, trustedAppsService, action.payload.artifacts); + } else if (action.payload.action === 'remove') { + removeTrustedAppsFromPolicy(context, store, action.payload.artifacts); } break; @@ -213,58 +219,26 @@ const searchTrustedApps = async ( } }; -interface UpdateTrustedAppWrapperProps { - entry: ImmutableObject<TrustedApp>; - policies: ImmutableArray<string>; -} - const updateTrustedApps = async ( store: ImmutableMiddlewareAPI<PolicyDetailsState, PolicyDetailsAction>, trustedAppsService: TrustedAppsService, - trustedAppsIds: ImmutableArray<string> + trustedApps: MaybeImmutable<TrustedApp[]> ) => { const state = store.getState(); const policyId = policyIdFromParams(state); - const availavleArtifacts = getAssignableArtifactsList(state); - - if (!availavleArtifacts || !availavleArtifacts.data.length) { - return; - } store.dispatch({ type: 'policyArtifactsUpdateTrustedAppsChanged', // Ignore will be fixed with when AsyncResourceState is refactored (#830) - // @ts-ignore + // @ts-expect-error payload: createLoadingResourceState({ previousState: createUninitialisedResourceState() }), }); try { - const trustedAppsUpdateActions = []; - - const updateTrustedApp = async ({ entry, policies }: UpdateTrustedAppWrapperProps) => - trustedAppsService.updateTrustedApp({ id: entry.id }, { - effectScope: { type: 'policy', policies: [...policies, policyId] }, - name: entry.name, - entries: entry.entries, - os: entry.os, - description: entry.description, - version: entry.version, - } as PostTrustedAppCreateRequest); - - for (const entryId of trustedAppsIds) { - const entry = find({ id: entryId }, availavleArtifacts.data) as ImmutableObject<TrustedApp>; - if (entry) { - const policies = entry.effectScope.type === 'policy' ? entry.effectScope.policies : []; - trustedAppsUpdateActions.push({ entry, policies }); - } - } - - const updatedTrustedApps = await pMap(trustedAppsUpdateActions, updateTrustedApp, { - concurrency: 5, - /** When set to false, instead of stopping when a promise rejects, it will wait for all the promises to settle - * and then reject with an aggregated error containing all the errors from the rejected promises. */ - stopOnError: false, - }); + const updatedTrustedApps = await trustedAppsService.assignPolicyToTrustedApps( + policyId, + trustedApps + ); store.dispatch({ type: 'policyArtifactsUpdateTrustedAppsChanged', @@ -275,9 +249,7 @@ const updateTrustedApps = async ( } catch (err) { store.dispatch({ type: 'policyArtifactsUpdateTrustedAppsChanged', - // Ignore will be fixed with when AsyncResourceState is refactored (#830) - // @ts-ignore - payload: createFailedResourceState(err.body ?? err), + payload: createFailedResourceState<PutTrustedAppUpdateResponse[]>(err.body ?? err), }); } }; @@ -371,3 +343,48 @@ const fetchAllPoliciesIfNeeded = async ( }); } }; + +const removeTrustedAppsFromPolicy = async ( + { trustedAppsService }: MiddlewareRunnerContext, + { getState, dispatch }: PolicyDetailsStore, + trustedApps: MaybeImmutable<TrustedApp[]> +): Promise<void> => { + const state = getState(); + + if (getTrustedAppsIsRemoving(state)) { + return; + } + + dispatch({ + type: 'policyDetailsTrustedAppsRemoveListStateChanged', + // @ts-expect-error will be fixed when AsyncResourceState is refactored (#830) + payload: createLoadingResourceState(getCurrentTrustedAppsRemoveListState(state)), + }); + + try { + const currentPolicyId = licensedPolicy(state)?.id; + + if (!currentPolicyId) { + throw new Error('current policy id not found'); + } + + const response = await trustedAppsService.removePolicyFromTrustedApps( + currentPolicyId, + trustedApps + ); + + dispatch({ + type: 'policyDetailsTrustedAppsRemoveListStateChanged', + payload: createLoadedResourceState({ artifacts: trustedApps, response }), + }); + + dispatch({ + type: 'policyDetailsTrustedAppsForceListDataRefresh', + }); + } catch (error) { + dispatch({ + type: 'policyDetailsTrustedAppsRemoveListStateChanged', + payload: createFailedResourceState<PolicyRemoveTrustedApps>(error.body || error), + }); + } +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts index 2ad7ac9c06dac..008bcd262ceff 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts @@ -40,5 +40,6 @@ export const initialPolicyDetailsState: () => Immutable<PolicyDetailsState> = () doesAnyTrustedAppExists: createUninitialisedResourceState(), assignedList: createUninitialisedResourceState(), policies: createUninitialisedResourceState(), + removeList: createUninitialisedResourceState(), }, }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/trusted_apps_reducer.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/trusted_apps_reducer.ts index fbf498797e804..f9d090647b1b5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/trusted_apps_reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/trusted_apps_reducer.ts @@ -90,5 +90,25 @@ export const policyTrustedAppsReducer: ImmutableReducer<PolicyDetailsState, AppA }; } + if (action.type === 'policyDetailsTrustedAppsRemoveListStateChanged') { + return { + ...state, + artifacts: { + ...state.artifacts, + removeList: action.payload, + }, + }; + } + + if (action.type === 'policyDetailsArtifactsResetRemove') { + return { + ...state, + artifacts: { + ...state.artifacts, + removeList: initialPolicyDetailsState().artifacts.removeList, + }, + }; + } + return state; }; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/trusted_apps_selectors.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/trusted_apps_selectors.ts index 3177f13ae77e8..8ddf38fbb32e7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/trusted_apps_selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/trusted_apps_selectors.ts @@ -221,3 +221,24 @@ export const getPolicyTrustedAppListError: PolicyDetailsSelector< return currentAssignedTrustedAppsState.error; } }); + +export const getCurrentTrustedAppsRemoveListState: PolicyDetailsSelector< + PolicyArtifactsState['removeList'] +> = (state) => state.artifacts.removeList; + +export const getTrustedAppsIsRemoving: PolicyDetailsSelector<boolean> = createSelector( + getCurrentTrustedAppsRemoveListState, + (removeListState) => isLoadingResourceState(removeListState) +); + +export const getTrustedAppsRemovalError: PolicyDetailsSelector<ServerApiError | undefined> = + createSelector(getCurrentTrustedAppsRemoveListState, (removeListState) => { + if (isFailedResourceState(removeListState)) { + return removeListState.error; + } + }); + +export const getTrustedAppsWasRemoveSuccessful: PolicyDetailsSelector<boolean> = createSelector( + getCurrentTrustedAppsRemoveListState, + (removeListState) => isLoadedResourceState(removeListState) +); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts index be38e591dd9da..aca0971621863 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpFetchOptionsWithPath } from 'kibana/public'; import { composeHttpHandlerMocks, httpHandlerMockFactory, @@ -71,7 +72,7 @@ export const getAPIError = () => ({ }); type PolicyDetailsTrustedAppsHttpMocksInterface = ResponseProvidersInterface<{ - policyTrustedAppsList: () => GetTrustedAppsListResponse; + policyTrustedAppsList: (options: HttpFetchOptionsWithPath) => GetTrustedAppsListResponse; }>; /** diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/types.ts b/x-pack/plugins/security_solution/public/management/pages/policy/types.ts index 7f8bf9c3872ea..283c3afb573b6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/types.ts @@ -16,6 +16,8 @@ import { PostTrustedAppCreateResponse, MaybeImmutable, GetTrustedAppsListResponse, + TrustedApp, + PutTrustedAppUpdateResponse, } from '../../../../common/endpoint/types'; import { ServerApiError } from '../../../common/types'; import { @@ -78,6 +80,11 @@ export interface PolicyAssignedTrustedApps { artifacts: GetTrustedAppsListResponse; } +export interface PolicyRemoveTrustedApps { + artifacts: TrustedApp[]; + response: PutTrustedAppUpdateResponse[]; +} + /** * Policy artifacts store state */ @@ -96,6 +103,8 @@ export interface PolicyArtifactsState { assignedList: AsyncResourceState<PolicyAssignedTrustedApps>; /** A list of all available polices */ policies: AsyncResourceState<GetPolicyListResponse>; + /** list of artifacts to remove. Holds the ids that were removed and the API response */ + removeList: AsyncResourceState<PolicyRemoveTrustedApps>; } export enum OS { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.tsx index 5f0c5cca0ad2c..59de05415f86b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.tsx @@ -60,18 +60,23 @@ interface ExceptionItemsSummaryProps { export const ExceptionItemsSummary = memo<ExceptionItemsSummaryProps>( ({ stats, isSmall = false }) => { const getItem = useCallback( - (stat: keyof GetExceptionSummaryResponse) => ( - <EuiFlexItem key={stat}> - <SummaryStat - value={stats?.[stat] ?? 0} - color={stat === 'total' ? 'primary' : 'default'} - key={stat} - isSmall={isSmall} - > - {SUMMARY_LABELS[stat]} - </SummaryStat> - </EuiFlexItem> - ), + (stat: keyof GetExceptionSummaryResponse) => { + if (stat !== 'total' && isSmall) { + return null; + } + return ( + <EuiFlexItem key={stat}> + <SummaryStat + value={stats?.[stat] ?? 0} + color={stat === 'total' && !isSmall ? 'primary' : 'default'} + key={stat} + isSmall={isSmall} + > + {SUMMARY_LABELS[stat]} + </SummaryStat> + </EuiFlexItem> + ); + }, [stats, isSmall] ); @@ -100,9 +105,11 @@ const SummaryStat: FC<{ value: number; color?: EuiBadgeProps['color']; isSmall?: gutterSize={isSmall ? 'xs' : 'l'} isSmall={isSmall} > - <EuiFlexItem grow={false} style={color === 'primary' ? CSS_BOLD : undefined}> - {children} - </EuiFlexItem> + {!isSmall ? ( + <EuiFlexItem grow={false} style={color === 'primary' ? CSS_BOLD : undefined}> + {children} + </EuiFlexItem> + ) : null} <EuiFlexItem grow={false}> <EuiBadge color={color}>{value}</EuiBadge> </EuiFlexItem> diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx index 08e8ec39dbaa8..54b1c37c7093f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_trusted_apps_card.tsx @@ -6,7 +6,7 @@ */ import React, { memo, useMemo, useState, useEffect, useRef } from 'react'; -import { EuiPanel, EuiText } from '@elastic/eui'; +import { EuiPanel, EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { GetExceptionSummaryResponse } from '../../../../../../../../common/endpoint/types'; @@ -14,7 +14,11 @@ import { GetExceptionSummaryResponse } from '../../../../../../../../common/endp import { useKibana, useToasts } from '../../../../../../../common/lib/kibana'; import { ExceptionItemsSummary } from './exception_items_summary'; import { TrustedAppsHttpService } from '../../../../../trusted_apps/service'; -import { StyledEuiFlexGridGroup, StyledEuiFlexGridItem } from './styled_components'; +import { + StyledEuiFlexGridGroup, + StyledEuiFlexGridItem, + StyledEuiFlexItem, +} from './styled_components'; interface FleetTrustedAppsCardProps { customLink: React.ReactNode; @@ -38,7 +42,7 @@ export const FleetTrustedAppsCard = memo<FleetTrustedAppsCardProps>( try { const response = await trustedAppsApi.getTrustedAppsSummary({ kuery: policyId - ? `exception-list-agnostic.attributes.tags:"policy:${policyId}" OR exception-list-agnostic.attributes.tags:"policy:all"` + ? `(exception-list-agnostic.attributes.tags:"policy:${policyId}" OR exception-list-agnostic.attributes.tags:"policy:all")` : undefined, }); if (isMounted) { @@ -72,21 +76,49 @@ export const FleetTrustedAppsCard = memo<FleetTrustedAppsCardProps>( /> ); + const cardGrid = useMemo(() => { + if (cardSize === 'm') { + return ( + <EuiFlexGroup + alignItems="baseline" + justifyContent="flexStart" + gutterSize="s" + direction="row" + responsive={false} + > + <EuiFlexItem grow={false}> + <EuiText> + <h5>{getTitleMessage()}</h5> + </EuiText> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <ExceptionItemsSummary stats={stats} isSmall={true} /> + </EuiFlexItem> + <StyledEuiFlexItem grow={1}>{customLink}</StyledEuiFlexItem> + </EuiFlexGroup> + ); + } else { + return ( + <StyledEuiFlexGridGroup alignItems="baseline" justifyContent="center"> + <StyledEuiFlexGridItem gridarea="title" alignitems="flex-start"> + <EuiText> + <h4>{getTitleMessage()}</h4> + </EuiText> + </StyledEuiFlexGridItem> + <StyledEuiFlexGridItem gridarea="summary" alignitems={'center'}> + <ExceptionItemsSummary stats={stats} isSmall={false} /> + </StyledEuiFlexGridItem> + <StyledEuiFlexGridItem gridarea="link" alignitems="flex-end"> + {customLink} + </StyledEuiFlexGridItem> + </StyledEuiFlexGridGroup> + ); + } + }, [cardSize, customLink, stats]); + return ( <EuiPanel hasShadow={false} paddingSize="l" hasBorder data-test-subj="fleetTrustedAppsCard"> - <StyledEuiFlexGridGroup alignItems="baseline" justifyContent="center" cardSize={cardSize}> - <StyledEuiFlexGridItem gridarea="title" alignitems="flex-start"> - <EuiText> - {cardSize === 'l' ? <h4>{getTitleMessage()}</h4> : <h5>{getTitleMessage()}</h5>} - </EuiText> - </StyledEuiFlexGridItem> - <StyledEuiFlexGridItem gridarea="summary"> - <ExceptionItemsSummary stats={stats} isSmall={cardSize === 'm'} /> - </StyledEuiFlexGridItem> - <StyledEuiFlexGridItem gridarea="link" alignitems="flex-end"> - {customLink} - </StyledEuiFlexGridItem> - </StyledEuiFlexGridGroup> + {cardGrid} </EuiPanel> ); } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/styled_components.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/styled_components.tsx index d2d5de5d43a3f..ad1d823677f22 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/styled_components.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/styled_components.tsx @@ -7,12 +7,9 @@ import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -export const StyledEuiFlexGridGroup = styled(EuiFlexGroup)<{ - cardSize?: 'm' | 'l'; -}>` +export const StyledEuiFlexGridGroup = styled(EuiFlexGroup)` display: grid; - grid-template-columns: ${({ cardSize = 'l' }) => - cardSize === 'l' ? '25% 45% 30%' : '30% 35% 35%'}; + grid-template-columns: 25% 45% 30%; grid-template-areas: 'title summary link'; `; @@ -25,3 +22,7 @@ export const StyledEuiFlexGridItem = styled(EuiFlexItem)<{ margin: 0px; padding: 12px; `; + +export const StyledEuiFlexItem = styled(EuiFlexItem)` + flex-direction: row-reverse; +`; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts index 82296730af686..c6b89b4137cc4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts @@ -71,6 +71,8 @@ export const usePolicyTrustedAppsNotification = () => { if (updateSuccessfull && updatedArtifacts && !wasAlreadyHandled.has(updatedArtifacts)) { wasAlreadyHandled.add(updatedArtifacts); + const updateCount = updatedArtifacts.length; + toasts.addSuccess({ title: i18n.translate( 'xpack.securitySolution.endpoint.policy.trustedApps.layout.flyout.toastSuccess.title', @@ -78,13 +80,22 @@ export const usePolicyTrustedAppsNotification = () => { defaultMessage: 'Success', } ), - text: i18n.translate( - 'xpack.securitySolution.endpoint.policy.trustedApps.layout.flyout.toastSuccess.text', - { - defaultMessage: '"{names}" has been added to your trusted applications list.', - values: { names: updatedArtifacts.map((artifact) => artifact.data.name).join(', ') }, - } - ), + text: + updateCount > 1 + ? i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.layout.flyout.toastSuccess.textMultiples', + { + defaultMessage: '{count} trusted applications have been added to your list.', + values: { count: updateCount }, + } + ) + : i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.layout.flyout.toastSuccess.textSingle', + { + defaultMessage: '"{name}" has been added to your trusted applications list.', + values: { name: updatedArtifacts[0]!.data.name }, + } + ), }); } else if (updateFailed) { toasts.addDanger( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.test.tsx index a586c3c9d1b29..c1d00f7a3f99b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.test.tsx @@ -21,6 +21,7 @@ import { createLoadedResourceState, isLoadedResourceState } from '../../../../.. import { getPolicyDetailsArtifactsListPath } from '../../../../../common/routing'; jest.mock('../../../../trusted_apps/service'); +jest.mock('../../../../../../common/components/user_privileges/use_endpoint_privileges'); let mockedContext: AppContextTestRender; let waitForAction: MiddlewareActionSpyHelper['waitForAction']; @@ -37,6 +38,11 @@ describe('Policy trusted apps flyout', () => { updateTrustedApp: () => ({ data: getMockCreateResponse(), }), + assignPolicyToTrustedApps: () => [ + { + data: getMockCreateResponse(), + }, + ], }; }); mockedContext = createAppRootMockRenderer(); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx index cd291ed9f6eb0..8728104aee637 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx @@ -25,6 +25,7 @@ import { EuiCallOut, EuiEmptyPrompt, } from '@elastic/eui'; +import { Dispatch } from 'redux'; import { policyDetails, getCurrentArtifactsLocation, @@ -42,10 +43,12 @@ import { } from '../../policy_hooks'; import { PolicyArtifactsAssignableList } from '../../artifacts/assignable'; import { SearchExceptions } from '../../../../../components/search_exceptions'; +import { AppAction } from '../../../../../../common/store/actions'; +import { MaybeImmutable, TrustedApp } from '../../../../../../../common/endpoint/types'; export const PolicyTrustedAppsFlyout = React.memo(() => { usePolicyTrustedAppsNotification(); - const dispatch = useDispatch(); + const dispatch = useDispatch<Dispatch<AppAction>>(); const [selectedArtifactIds, setSelectedArtifactIds] = useState<string[]>([]); const location = usePolicyDetailsSelector(getCurrentArtifactsLocation); const policyItem = usePolicyDetailsSelector(policyDetails); @@ -85,9 +88,14 @@ export const PolicyTrustedAppsFlyout = React.memo(() => { const handleOnConfirmAction = useCallback(() => { dispatch({ type: 'policyArtifactsUpdateTrustedApps', - payload: { trustedAppIds: selectedArtifactIds }, + payload: { + action: 'assign', + artifacts: selectedArtifactIds.map<MaybeImmutable<TrustedApp>>((selectedId) => { + return assignableArtifactsList?.data?.find((trustedApp) => trustedApp.id === selectedId)!; + }), + }, }); - }, [dispatch, selectedArtifactIds]); + }, [assignableArtifactsList?.data, dispatch, selectedArtifactIds]); const handleOnSearch = useCallback( (filter) => { @@ -241,7 +249,7 @@ export const PolicyTrustedAppsFlyout = React.memo(() => { > <FormattedMessage id="xpack.securitySolution.endpoint.policy.trustedApps.layout.flyout.confirm" - defaultMessage="Assing to {policyName}" + defaultMessage="Assign to {policyName}" values={{ policyName, }} diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx index 07b62d13e8edc..83709c50b76fa 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx @@ -13,11 +13,19 @@ import { getPolicyDetailsArtifactsListPath } from '../../../../../common/routing import { PolicyTrustedAppsList } from './policy_trusted_apps_list'; import React from 'react'; import { policyDetailsPageAllApiHttpMocks } from '../../../test_utils'; -import { isFailedResourceState, isLoadedResourceState } from '../../../../../state'; +import { + createLoadingResourceState, + createUninitialisedResourceState, + isFailedResourceState, + isLoadedResourceState, +} from '../../../../../state'; import { fireEvent, within, act, waitFor } from '@testing-library/react'; import { APP_ID } from '../../../../../../../common/constants'; describe('when rendering the PolicyTrustedAppsList', () => { + // The index (zero based) of the card created by the generator that is policy specific + const POLICY_SPECIFIC_CARD_INDEX = 2; + let appTestContext: AppContextTestRender; let renderResult: ReturnType<AppContextTestRender['render']>; let render: (waitForLoadedState?: boolean) => Promise<ReturnType<AppContextTestRender['render']>>; @@ -84,8 +92,19 @@ describe('when rendering the PolicyTrustedAppsList', () => { }; }); - // FIXME: implement this test once PR #113802 is merged - it.todo('should show loading spinner if checking to see if trusted apps exist'); + it('should show loading spinner if checking to see if trusted apps exist', async () => { + await render(); + act(() => { + appTestContext.store.dispatch({ + type: 'policyArtifactsDeosAnyTrustedAppExists', + // Ignore will be fixed with when AsyncResourceState is refactored (#830) + // @ts-ignore + payload: createLoadingResourceState({ previousState: createUninitialisedResourceState() }), + }); + }); + + expect(renderResult.getByTestId('policyTrustedAppsGrid-loading')).not.toBeNull(); + }); it('should show total number of of items being displayed', async () => { await render(); @@ -163,40 +182,68 @@ describe('when rendering the PolicyTrustedAppsList', () => { ); }); - it('should display policy names on assignment context menu', async () => { - const retrieveAllPolicies = waitForAction('policyDetailsListOfAllPoliciesStateChanged', { - validate({ payload }) { - return isLoadedResourceState(payload); - }, - }); + it('should show dialog when remove action is clicked', async () => { await render(); - await retrieveAllPolicies; + await toggleCardActionMenu(POLICY_SPECIFIC_CARD_INDEX); act(() => { - fireEvent.click( - within(getCardByIndexPosition(2)).getByTestId( - 'policyTrustedAppsGrid-card-header-effectScope-popupMenu-button' + fireEvent.click(renderResult.getByTestId('policyTrustedAppsGrid-removeAction')); + }); + + await waitFor(() => expect(renderResult.getByTestId('confirmModalBodyText'))); + }); + + describe('and artifact is policy specific', () => { + const renderAndClickOnEffectScopePopupButton = async () => { + const retrieveAllPolicies = waitForAction('policyDetailsListOfAllPoliciesStateChanged', { + validate({ payload }) { + return isLoadedResourceState(payload); + }, + }); + await render(); + await retrieveAllPolicies; + act(() => { + fireEvent.click( + within(getCardByIndexPosition(POLICY_SPECIFIC_CARD_INDEX)).getByTestId( + 'policyTrustedAppsGrid-card-header-effectScope-popupMenu-button' + ) + ); + }); + await waitFor(() => + expect( + renderResult.getByTestId( + 'policyTrustedAppsGrid-card-header-effectScope-popupMenu-popoverPanel' + ) ) ); - }); - await waitFor(() => + }; + + it('should display policy names on assignment context menu', async () => { + await renderAndClickOnEffectScopePopupButton(); + expect( - renderResult.getByTestId( - 'policyTrustedAppsGrid-card-header-effectScope-popupMenu-popoverPanel' - ) - ) - ); + renderResult.getByTestId('policyTrustedAppsGrid-card-header-effectScope-popupMenu-item-0') + .textContent + ).toEqual('Endpoint Policy 0'); + expect( + renderResult.getByTestId('policyTrustedAppsGrid-card-header-effectScope-popupMenu-item-1') + .textContent + ).toEqual('Endpoint Policy 1'); + }); - expect( - renderResult.getByTestId('policyTrustedAppsGrid-card-header-effectScope-popupMenu-item-0') - .textContent - ).toEqual('Endpoint Policy 0'); - expect( - renderResult.getByTestId('policyTrustedAppsGrid-card-header-effectScope-popupMenu-item-1') - .textContent - ).toEqual('Endpoint Policy 1'); - }); + it('should navigate to policy details when clicking policy on assignment context menu', async () => { + await renderAndClickOnEffectScopePopupButton(); + + act(() => { + fireEvent.click( + renderResult.getByTestId('policyTrustedAppsGrid-card-header-effectScope-popupMenu-item-0') + ); + }); - it.todo('should navigate to policy details when clicking policy on assignment context menu'); + expect(appTestContext.history.location.pathname).toEqual( + '/administration/policy/ddf6570b-9175-4a6d-b288-61a09771c647/settings' + ); + }); + }); it('should handle pagination changes', async () => { await render(); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx index 6793bee9c3c01..cb29d0ff868ac 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx @@ -37,6 +37,7 @@ import { APP_ID } from '../../../../../../../common/constants'; import { ContextMenuItemNavByRouterProps } from '../../../../../components/context_menu_with_router_support/context_menu_item_nav_by_router'; import { ArtifactEntryCollapsibleCardProps } from '../../../../../components/artifact_entry_card'; import { useTestIdGenerator } from '../../../../../components/hooks/use_test_id_generator'; +import { RemoveTrustedAppFromPolicyModal } from './remove_trusted_app_from_policy_modal'; const DATA_TEST_SUBJ = 'policyTrustedAppsGrid'; @@ -56,6 +57,8 @@ export const PolicyTrustedAppsList = memo(() => { const trustedAppsApiError = usePolicyDetailsSelector(getPolicyTrustedAppListError); const [isCardExpanded, setCardExpanded] = useState<Record<string, boolean>>({}); + const [trustedAppsForRemoval, setTrustedAppsForRemoval] = useState<typeof trustedAppItems>([]); + const [showRemovalModal, setShowRemovalModal] = useState<boolean>(false); const handlePageChange = useCallback<ArtifactCardGridProps['onPageChange']>( ({ pageIndex, pageSize }) => { @@ -100,6 +103,7 @@ export const PolicyTrustedAppsList = memo(() => { const newCardProps = new Map(); for (const trustedApp of trustedAppItems) { + const isGlobal = trustedApp.effectScope.type === 'global'; const viewUrlPath = getTrustedAppsListPath({ id: trustedApp.id, show: 'edit' }); const assignedPoliciesMenuItems: ArtifactEntryCollapsibleCardProps['policies'] = trustedApp.effectScope.type === 'global' @@ -142,6 +146,29 @@ export const PolicyTrustedAppsList = memo(() => { navigateOptions: { path: viewUrlPath }, 'data-test-subj': getTestId('viewFullDetailsAction'), }, + { + icon: 'trash', + children: i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeAction', + { defaultMessage: 'Remove from policy' } + ), + onClick: () => { + setTrustedAppsForRemoval([trustedApp]); + setShowRemovalModal(true); + }, + disabled: isGlobal, + toolTipContent: isGlobal + ? i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeActionNotAllowed', + { + defaultMessage: + 'Globally applied trusted applications cannot be removed from policy.', + } + ) + : undefined, + toolTipPosition: 'top', + 'data-test-subj': getTestId('removeAction'), + }, ], policies: assignedPoliciesMenuItems, }; @@ -159,6 +186,15 @@ export const PolicyTrustedAppsList = memo(() => { [cardProps] ); + const handleRemoveModalClose = useCallback(() => { + setShowRemovalModal(false); + }, []); + + // Anytime a new set of data (trusted apps) is retrieved, reset the card expand state + useEffect(() => { + setCardExpanded({}); + }, [trustedAppItems]); + // if an error occurred while loading the data, show toast useEffect(() => { if (trustedAppsApiError) { @@ -170,18 +206,13 @@ export const PolicyTrustedAppsList = memo(() => { } }, [toasts, trustedAppsApiError]); - // Anytime a new set of data (trusted apps) is retrieved, reset the card expand state - useEffect(() => { - setCardExpanded({}); - }, [trustedAppItems]); - if (hasTrustedApps.loading || isTrustedAppExistsCheckLoading) { return ( <EuiPageTemplate template="centeredContent"> <EuiLoadingSpinner className="essentialAnimation" size="xl" - data-test-subj={DATA_TEST_SUBJ} + data-test-subj={getTestId('loading')} /> </EuiPageTemplate> ); @@ -205,6 +236,13 @@ export const PolicyTrustedAppsList = memo(() => { pagination={pagination as Pagination} data-test-subj={DATA_TEST_SUBJ} /> + + {showRemovalModal && ( + <RemoveTrustedAppFromPolicyModal + trustedApps={trustedAppsForRemoval} + onClose={handleRemoveModalClose} + /> + )} </> ); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx new file mode 100644 index 0000000000000..fc2926bc65d3a --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + AppContextTestRender, + createAppRootMockRenderer, +} from '../../../../../../common/mock/endpoint'; +import { getPolicyDetailsArtifactsListPath } from '../../../../../common/routing'; +import { isLoadedResourceState } from '../../../../../state'; +import React from 'react'; +import { fireEvent, act } from '@testing-library/react'; +import { policyDetailsPageAllApiHttpMocks } from '../../../test_utils'; +import { + RemoveTrustedAppFromPolicyModal, + RemoveTrustedAppFromPolicyModalProps, +} from './remove_trusted_app_from_policy_modal'; +import { PolicyArtifactsUpdateTrustedApps } from '../../../store/policy_details/action/policy_trusted_apps_action'; +import { Immutable } from '../../../../../../../common/endpoint/types'; +import { HttpFetchOptionsWithPath } from 'kibana/public'; + +describe('When using the RemoveTrustedAppFromPolicyModal component', () => { + let appTestContext: AppContextTestRender; + let renderResult: ReturnType<AppContextTestRender['render']>; + let render: (waitForLoadedState?: boolean) => Promise<ReturnType<AppContextTestRender['render']>>; + let waitForAction: AppContextTestRender['middlewareSpy']['waitForAction']; + let mockedApis: ReturnType<typeof policyDetailsPageAllApiHttpMocks>; + let onCloseHandler: jest.MockedFunction<RemoveTrustedAppFromPolicyModalProps['onClose']>; + let trustedApps: RemoveTrustedAppFromPolicyModalProps['trustedApps']; + + beforeEach(() => { + appTestContext = createAppRootMockRenderer(); + waitForAction = appTestContext.middlewareSpy.waitForAction; + onCloseHandler = jest.fn(); + mockedApis = policyDetailsPageAllApiHttpMocks(appTestContext.coreStart.http); + trustedApps = [ + mockedApis.responseProvider.policyTrustedAppsList({ query: {} } as HttpFetchOptionsWithPath) + .data[0], + ]; + + render = async (waitForLoadedState: boolean = true) => { + const pendingDataLoadState = waitForLoadedState + ? Promise.all([ + waitForAction('serverReturnedPolicyDetailsData'), + waitForAction('assignedTrustedAppsListStateChanged', { + validate({ payload }) { + return isLoadedResourceState(payload); + }, + }), + ]) + : Promise.resolve(); + + appTestContext.history.push( + getPolicyDetailsArtifactsListPath('ddf6570b-9175-4a6d-b288-61a09771c647') + ); + renderResult = appTestContext.render( + <RemoveTrustedAppFromPolicyModal trustedApps={trustedApps} onClose={onCloseHandler} /> + ); + + await pendingDataLoadState; + + return renderResult; + }; + }); + + const getConfirmButton = (): HTMLButtonElement => + renderResult.getByTestId('confirmModalConfirmButton') as HTMLButtonElement; + + const clickConfirmButton = async ( + waitForActionDispatch: boolean = false + ): Promise<Immutable<PolicyArtifactsUpdateTrustedApps> | undefined> => { + const pendingConfirmStoreAction = waitForAction('policyArtifactsUpdateTrustedApps'); + + act(() => { + fireEvent.click(getConfirmButton()); + }); + + let response: PolicyArtifactsUpdateTrustedApps | undefined; + + if (waitForActionDispatch) { + await act(async () => { + response = await pendingConfirmStoreAction; + }); + } + + return response; + }; + + const clickCancelButton = () => { + act(() => { + fireEvent.click(renderResult.getByTestId('confirmModalCancelButton')); + }); + }; + + const clickCloseButton = () => { + act(() => { + fireEvent.click(renderResult.baseElement.querySelector('button.euiModal__closeIcon')!); + }); + }; + + it.each([ + ['cancel', clickCancelButton], + ['close', clickCloseButton], + ])('should call `onClose` callback when %s button is clicked', async (__, clickButton) => { + await render(); + clickButton(); + + expect(onCloseHandler).toHaveBeenCalled(); + }); + + it('should dispatch action when confirmed', async () => { + await render(); + const confirmedAction = await clickConfirmButton(true); + + expect(confirmedAction!.payload).toEqual({ + action: 'remove', + artifacts: trustedApps, + }); + }); + + it.skip('should disable and show loading state on confirm button while update is underway', async () => { + await render(); + await clickConfirmButton(true); + const confirmButton = getConfirmButton(); + + // FIXME:PT will finish test in a subsequent PR (issue created #1876) + // GETTING ERROR: + // Error: current policy id not found + // // at removeTrustedAppsFromPolicy (.../x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/middleware/policy_trusted_apps_middleware.ts:368:13) + // // at policyTrustedAppsMiddlewareRunner (.../x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/middleware/policy_trusted_apps_middleware.ts:93:9) + + expect(confirmButton.disabled).toBe(true); + expect(confirmButton.querySelector('.euiLoadingSpinner')).not.toBeNull(); + }); + + it.each([ + ['cancel', clickCancelButton], + ['close', clickCloseButton], + ])( + 'should prevent dialog dismissal if %s button is clicked while update is underway', + (__, clickButton) => { + // TODO: implement test + } + ); + + it.todo('should show error toast if removal failed'); + + it.todo('should show success toast and close modal when removed is successful'); + + it.todo('should show single removal success message'); + + it.todo('should show multiples removal success message'); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.tsx new file mode 100644 index 0000000000000..c43c28ec82829 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.tsx @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback, useEffect, useMemo } from 'react'; +import { EuiCallOut, EuiConfirmModal, EuiSpacer, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { useDispatch } from 'react-redux'; +import { Dispatch } from 'redux'; +import { Immutable, TrustedApp } from '../../../../../../../common/endpoint/types'; +import { AppAction } from '../../../../../../common/store/actions'; +import { usePolicyDetailsSelector } from '../../policy_hooks'; +import { + getTrustedAppsIsRemoving, + getTrustedAppsRemovalError, + getTrustedAppsWasRemoveSuccessful, + policyDetails, +} from '../../../store/policy_details/selectors'; +import { useToasts } from '../../../../../../common/lib/kibana'; + +export interface RemoveTrustedAppFromPolicyModalProps { + trustedApps: Immutable<TrustedApp[]>; + onClose: () => void; +} + +export const RemoveTrustedAppFromPolicyModal = memo<RemoveTrustedAppFromPolicyModalProps>( + ({ trustedApps, onClose }) => { + const toasts = useToasts(); + const dispatch = useDispatch<Dispatch<AppAction>>(); + + const policyName = usePolicyDetailsSelector(policyDetails)?.name; + const isRemoving = usePolicyDetailsSelector(getTrustedAppsIsRemoving); + const removeError = usePolicyDetailsSelector(getTrustedAppsRemovalError); + const wasSuccessful = usePolicyDetailsSelector(getTrustedAppsWasRemoveSuccessful); + + const removedToastMessage: string = useMemo(() => { + const count = trustedApps.length; + + if (count === 0) { + return ''; + } + + if (count > 1) { + return i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.successMultiplesToastText', + { + defaultMessage: '{count} trusted apps have been removed from {policyName} policy', + values: { count, policyName }, + } + ); + } + + return i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.successToastText', + { + defaultMessage: '"{trustedAppName}" has been removed from "{policyName}" policy', + values: { trustedAppName: trustedApps[0].name, policyName }, + } + ); + }, [policyName, trustedApps]); + + const handleModalClose = useCallback(() => { + if (!isRemoving) { + onClose(); + } + }, [isRemoving, onClose]); + + const handleModalConfirm = useCallback(() => { + dispatch({ + type: 'policyArtifactsUpdateTrustedApps', + payload: { action: 'remove', artifacts: trustedApps }, + }); + }, [dispatch, trustedApps]); + + useEffect(() => { + // When component is un-mounted, reset the state for remove in the store + return () => { + dispatch({ type: 'policyDetailsArtifactsResetRemove' }); + }; + }, [dispatch]); + + useEffect(() => { + if (removeError) { + toasts.addError(removeError as unknown as Error, { + title: i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.errorToastTitle', + { + defaultMessage: 'Error while attempt to remove trusted application', + } + ), + }); + } + }, [removeError, toasts]); + + useEffect(() => { + if (wasSuccessful) { + toasts.addSuccess({ + title: i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.successToastTitle', + { defaultMessage: 'Successfully removed' } + ), + text: removedToastMessage, + }); + handleModalClose(); + } + }, [handleModalClose, policyName, removedToastMessage, toasts, trustedApps, wasSuccessful]); + + return ( + <EuiConfirmModal + onCancel={handleModalClose} + onConfirm={handleModalConfirm} + title={i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.title', + { defaultMessage: 'Remove trusted application from policy' } + )} + cancelButtonText={i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.cancelLabel', + { defaultMessage: 'Cancel' } + )} + confirmButtonText={i18n.translate( + 'xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.confirmLabel', + { + defaultMessage: 'Remove from policy', + } + )} + isLoading={isRemoving} + > + <EuiCallOut color="warning" iconType="help"> + <p> + <FormattedMessage + id="xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.messageCallout" + defaultMessage="This trusted application will be removed only from this policy and can still be found and managed from the trusted applications page." + /> + </p> + </EuiCallOut> + + <EuiSpacer /> + + <EuiText size="s"> + <p> + <FormattedMessage + id="xpack.securitySolution.endpoint.policy.trustedApps.list.removeDialog.message" + defaultMessage="Are you sure you wish to continue?" + /> + </p> + </EuiText> + </EuiConfirmModal> + ); + } +); +RemoveTrustedAppFromPolicyModal.displayName = 'RemoveTrustedAppFromPolicyModal'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts index 09aa80ffae495..b59fb6cfdd2f7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts @@ -7,6 +7,7 @@ import { HttpStart } from 'kibana/public'; +import pMap from 'p-map'; import { TRUSTED_APPS_CREATE_API, TRUSTED_APPS_DELETE_API, @@ -29,10 +30,14 @@ import { GetOneTrustedAppRequestParams, GetOneTrustedAppResponse, GetTrustedAppsSummaryRequest, -} from '../../../../../common/endpoint/types/trusted_apps'; + TrustedApp, + MaybeImmutable, +} from '../../../../../common/endpoint/types'; import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables'; import { sendGetEndpointSpecificPackagePolicies } from '../../policy/store/services/ingest'; +import { toUpdateTrustedApp } from '../../../../../common/endpoint/service/trusted_apps/to_update_trusted_app'; +import { isGlobalEffectScope } from '../state/type_guards'; export interface TrustedAppsService { getTrustedApp(params: GetOneTrustedAppRequestParams): Promise<GetOneTrustedAppResponse>; @@ -46,8 +51,23 @@ export interface TrustedAppsService { getPolicyList( options?: Parameters<typeof sendGetEndpointSpecificPackagePolicies>[1] ): ReturnType<typeof sendGetEndpointSpecificPackagePolicies>; + assignPolicyToTrustedApps( + policyId: string, + trustedApps: MaybeImmutable<TrustedApp[]> + ): Promise<PutTrustedAppUpdateResponse[]>; + removePolicyFromTrustedApps( + policyId: string, + trustedApps: MaybeImmutable<TrustedApp[]> + ): Promise<PutTrustedAppUpdateResponse[]>; } +const P_MAP_OPTIONS = Object.freeze<pMap.Options>({ + concurrency: 5, + /** When set to false, instead of stopping when a promise rejects, it will wait for all the promises to settle + * and then reject with an aggregated error containing all the errors from the rejected promises. */ + stopOnError: false, +}); + export class TrustedAppsHttpService implements TrustedAppsService { constructor(private http: HttpStart) {} @@ -92,4 +112,79 @@ export class TrustedAppsHttpService implements TrustedAppsService { getPolicyList(options?: Parameters<typeof sendGetEndpointSpecificPackagePolicies>[1]) { return sendGetEndpointSpecificPackagePolicies(this.http, options); } + + /** + * Assign a policy to trusted apps. Note that Trusted Apps MUST NOT be global + * + * @param policyId + * @param trustedApps[] + */ + assignPolicyToTrustedApps( + policyId: string, + trustedApps: MaybeImmutable<TrustedApp[]> + ): Promise<PutTrustedAppUpdateResponse[]> { + return this._handleAssignOrRemovePolicyId('assign', policyId, trustedApps); + } + + /** + * Remove a policy from trusted apps. Note that Trusted Apps MUST NOT be global + * + * @param policyId + * @param trustedApps[] + */ + removePolicyFromTrustedApps( + policyId: string, + trustedApps: MaybeImmutable<TrustedApp[]> + ): Promise<PutTrustedAppUpdateResponse[]> { + return this._handleAssignOrRemovePolicyId('remove', policyId, trustedApps); + } + + private _handleAssignOrRemovePolicyId( + action: 'assign' | 'remove', + policyId: string, + trustedApps: MaybeImmutable<TrustedApp[]> + ): Promise<PutTrustedAppUpdateResponse[]> { + if (policyId.trim() === '') { + throw new Error('policy ID is required'); + } + + if (trustedApps.length === 0) { + throw new Error('at least one trusted app is required'); + } + + return pMap( + trustedApps, + async (trustedApp) => { + if (isGlobalEffectScope(trustedApp.effectScope)) { + throw new Error( + `Unable to update trusted app [${trustedApp.id}] policy assignment. It's effectScope is 'global'` + ); + } + + const policies: string[] = !isGlobalEffectScope(trustedApp.effectScope) + ? [...trustedApp.effectScope.policies] + : []; + + const indexOfPolicyId = policies.indexOf(policyId); + + if (action === 'assign' && indexOfPolicyId === -1) { + policies.push(policyId); + } else if (action === 'remove' && indexOfPolicyId !== -1) { + policies.splice(indexOfPolicyId, 1); + } + + return this.updateTrustedApp( + { id: trustedApp.id }, + { + ...toUpdateTrustedApp(trustedApp), + effectScope: { + type: 'policy', + policies, + }, + } + ); + }, + P_MAP_OPTIONS + ); + } } diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts index f64003ec6ad91..4455baddb047c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts @@ -54,6 +54,8 @@ const createTrustedAppsServiceMock = (): jest.Mocked<TrustedAppsService> => ({ getPolicyList: jest.fn(), updateTrustedApp: jest.fn(), getTrustedApp: jest.fn(), + assignPolicyToTrustedApps: jest.fn(), + removePolicyFromTrustedApps: jest.fn(), }); const createStoreSetup = (trustedAppsService: TrustedAppsService) => { diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts index f772986bff146..0ff6282f8a018 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts @@ -412,8 +412,8 @@ const fetchEditTrustedAppIfNeeded = async ( dispatch({ type: 'trustedAppCreationEditItemStateChanged', payload: { - type: 'LoadingResourceState', // @ts-expect-error-next-line will be fixed with when AsyncResourceState is refactored (#830) + type: 'LoadingResourceState', previousState: editItemState(currentState)!, }, }); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx index 7abf5d77dd5e9..f72d54aa9e3c9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx @@ -8,22 +8,25 @@ import { EuiButton, EuiButtonEmpty, + EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiFlyout, EuiFlyoutBody, EuiFlyoutFooter, EuiFlyoutHeader, + EuiLink, EuiSpacer, EuiText, EuiTitle, } from '@elastic/eui'; -import React, { memo, useCallback, useEffect, useMemo } from 'react'; +import React, { memo, useCallback, useEffect, useState, useMemo } from 'react'; import { EuiFlyoutProps } from '@elastic/eui/src/components/flyout/flyout'; import { FormattedMessage } from '@kbn/i18n/react'; import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; +import _ from 'lodash'; import { CreateTrustedAppForm, CreateTrustedAppFormProps } from './create_trusted_app_form'; import { editTrustedAppFetchError, @@ -43,10 +46,14 @@ import { useTrustedAppsSelector } from '../hooks'; import { ABOUT_TRUSTED_APPS, CREATE_TRUSTED_APP_ERROR } from '../translations'; import { defaultNewTrustedApp } from '../../store/builders'; import { getTrustedAppsListPath } from '../../../../common/routing'; -import { useToasts } from '../../../../../common/lib/kibana'; +import { useKibana, useToasts } from '../../../../../common/lib/kibana'; import { useTestIdGenerator } from '../../../../components/hooks/use_test_id_generator'; +import { useLicense } from '../../../../../common/hooks/use_license'; +import { isGlobalEffectScope } from '../../state/type_guards'; +import { NewTrustedApp } from '../../../../../../common/endpoint/types'; +import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -type CreateTrustedAppFlyoutProps = Omit<EuiFlyoutProps, 'hideCloseButton'>; +export type CreateTrustedAppFlyoutProps = Omit<EuiFlyoutProps, 'hideCloseButton'>; export const CreateTrustedAppFlyout = memo<CreateTrustedAppFlyoutProps>( ({ onClose, ...flyoutProps }) => { const dispatch = useDispatch<(action: AppAction) => void>(); @@ -63,6 +70,9 @@ export const CreateTrustedAppFlyout = memo<CreateTrustedAppFlyoutProps>( const trustedAppFetchError = useTrustedAppsSelector(editTrustedAppFetchError); const formValues = useTrustedAppsSelector(getCreationDialogFormEntry) || defaultNewTrustedApp(); const location = useTrustedAppsSelector(getCurrentLocation); + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const docLinks = useKibana().services.docLinks; + const [isFormDirty, setIsFormDirty] = useState(false); const dataTestSubj = flyoutProps['data-test-subj']; @@ -124,10 +134,28 @@ export const CreateTrustedAppFlyout = memo<CreateTrustedAppFlyoutProps>( type: 'trustedAppCreationDialogFormStateUpdated', payload: { entry: newFormState.item, isValid: newFormState.isValid }, }); + if (_.isEqual(formValues, newFormState.item) === false) { + setIsFormDirty(true); + } }, - [dispatch] + + [dispatch, formValues] + ); + + const isTrustedAppsByPolicyEnabled = useIsExperimentalFeatureEnabled( + 'trustedAppsByPolicyEnabled' ); + const isGlobal = useMemo(() => { + return isGlobalEffectScope((formValues as NewTrustedApp).effectScope); + }, [formValues]); + + const showExpiredLicenseBanner = useMemo(() => { + return ( + isTrustedAppsByPolicyEnabled && !isPlatinumPlus && isEditMode && (!isGlobal || isFormDirty) + ); + }, [isTrustedAppsByPolicyEnabled, isPlatinumPlus, isEditMode, isGlobal, isFormDirty]); + // If there was a failure trying to retrieve the Trusted App for edit item, // then redirect back to the list ++ show toast message. useEffect(() => { @@ -181,7 +209,28 @@ export const CreateTrustedAppFlyout = memo<CreateTrustedAppFlyoutProps>( </h2> </EuiTitle> </EuiFlyoutHeader> - + {showExpiredLicenseBanner && ( + <EuiCallOut + title={i18n.translate( + 'xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseTitle', + { defaultMessage: 'Expired License' } + )} + color="warning" + iconType="help" + data-test-subj={getTestId('expired-license-callout')} + > + <FormattedMessage + id="xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseMessage" + defaultMessage="Your Kibana license has been downgraded. Future policy configurations will now be globally assigned to all policies. For more information, see our " + /> + <EuiLink external href={`${docLinks.links.securitySolution.trustedApps}`}> + <FormattedMessage + id="xpack.securitySolution.trustedapps.docsLink" + defaultMessage="Trusted applications documentation." + /> + </EuiLink> + </EuiCallOut> + )} <EuiFlyoutBody> <EuiText size="xs"> <h3> @@ -203,6 +252,8 @@ export const CreateTrustedAppFlyout = memo<CreateTrustedAppFlyoutProps>( fullWidth onChange={handleFormOnChange} isInvalid={!!creationErrors} + isEditMode={isEditMode} + isDirty={isFormDirty} error={creationErrorsMessage} policies={policies} trustedApp={formValues} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx index 45eaa2c890a78..d3b4a541bd18d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx @@ -24,10 +24,23 @@ import { defaultNewTrustedApp } from '../../store/builders'; import { forceHTMLElementOffsetWidth } from './effected_policy_select/test_utils'; import { EndpointDocGenerator } from '../../../../../../common/endpoint/generate_data'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; +import { licenseService } from '../../../../../common/hooks/use_license'; jest.mock('../../../../../common/hooks/use_experimental_features'); const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock; +jest.mock('../../../../../common/hooks/use_license', () => { + const licenseServiceInstance = { + isPlatinumPlus: jest.fn(), + }; + return { + licenseService: licenseServiceInstance, + useLicense: () => { + return licenseServiceInstance; + }, + }; +}); + describe('When using the Trusted App Form', () => { const dataTestSubjForForm = 'createForm'; const generator = new EndpointDocGenerator('effected-policy-select'); @@ -112,6 +125,7 @@ describe('When using the Trusted App Form', () => { beforeEach(() => { resetHTMLElementOffsetWidth = forceHTMLElementOffsetWidth(); useIsExperimentalFeatureEnabledMock.mockReturnValue(true); + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); mockedContext = createAppRootMockRenderer(); @@ -120,6 +134,8 @@ describe('When using the Trusted App Form', () => { formProps = { 'data-test-subj': dataTestSubjForForm, trustedApp: latestUpdatedTrustedApp, + isEditMode: false, + isDirty: false, onChange: jest.fn((updates) => { latestUpdatedTrustedApp = updates.item; }), @@ -303,6 +319,58 @@ describe('When using the Trusted App Form', () => { }); }); + describe('the Policy Selection area when the license downgrades to gold or below', () => { + beforeEach(() => { + // select per policy for trusted app + const policy = generator.generatePolicyPackagePolicy(); + policy.name = 'test policy A'; + policy.id = '123'; + + formProps.policies.options = [policy]; + + (formProps.trustedApp as NewTrustedApp).effectScope = { + type: 'policy', + policies: ['123'], + }; + + formProps.isEditMode = true; + + // downgrade license + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); + }); + + it('maintains policy configuration but does not allow the user to edit add/remove individual policies in edit mode', () => { + render(); + const perPolicyButton = renderResult.getByTestId( + `${dataTestSubjForForm}-effectedPolicies-perPolicy` + ) as HTMLButtonElement; + + expect(perPolicyButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); + expect(renderResult.getByTestId('policy-123').getAttribute('aria-disabled')).toEqual('true'); + expect(renderResult.getByTestId('policy-123-checkbox')).toBeChecked(); + }); + it("allows the user to set the trusted app entry to 'Global' in the edit option", () => { + render(); + const globalButtonInput = renderResult.getByTestId('globalPolicy') as HTMLButtonElement; + + reactTestingLibrary.act(() => { + fireEvent.click(globalButtonInput); + }); + + expect(formProps.onChange.mock.calls[0][0].item.effectScope.type).toBe('global'); + }); + it('hides the policy assignment section if the TA is set to global', () => { + (formProps.trustedApp as NewTrustedApp).effectScope = { + type: 'global', + }; + expect(renderResult.queryByTestId(`${dataTestSubjForForm}-effectedPolicies`)).toBeNull(); + }); + it('hides the policy assignment section if the user is adding a new TA', () => { + formProps.isEditMode = false; + expect(renderResult.queryByTestId(`${dataTestSubjForForm}-effectedPolicies`)).toBeNull(); + }); + }); + describe('and the user visits required fields but does not fill them out', () => { beforeEach(() => { render(); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx index 5db9a8557fa10..50485ccde00ad 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx @@ -48,6 +48,7 @@ import { EffectedPolicySelectProps, } from './effected_policy_select'; import { useTestIdGenerator } from '../../../../components/hooks/use_test_id_generator'; +import { useLicense } from '../../../../../common/hooks/use_license'; const OPERATING_SYSTEMS: readonly OperatingSystem[] = [ OperatingSystem.MAC, @@ -189,6 +190,8 @@ export type CreateTrustedAppFormProps = Pick< > & { /** The trusted app values that will be passed to the form */ trustedApp: MaybeImmutable<NewTrustedApp>; + isEditMode: boolean; + isDirty: boolean; onChange: (state: TrustedAppFormState) => void; /** Setting passed on to the EffectedPolicySelect component */ policies: Pick<EffectedPolicySelectProps, 'options' | 'isLoading'>; @@ -196,7 +199,15 @@ export type CreateTrustedAppFormProps = Pick< fullWidth?: boolean; }; export const CreateTrustedAppForm = memo<CreateTrustedAppFormProps>( - ({ fullWidth, onChange, trustedApp: _trustedApp, policies = { options: [] }, ...formProps }) => { + ({ + fullWidth, + isEditMode, + isDirty, + onChange, + trustedApp: _trustedApp, + policies = { options: [] }, + ...formProps + }) => { const trustedApp = _trustedApp as NewTrustedApp; const dataTestSubj = formProps['data-test-subj']; @@ -205,6 +216,16 @@ export const CreateTrustedAppForm = memo<CreateTrustedAppFormProps>( 'trustedAppsByPolicyEnabled' ); + const isPlatinumPlus = useLicense().isPlatinumPlus(); + + const isGlobal = useMemo(() => { + return isGlobalEffectScope(trustedApp.effectScope); + }, [trustedApp]); + + const hideAssignmentSection = useMemo(() => { + return !isPlatinumPlus && (!isEditMode || (isGlobal && !isDirty)); + }, [isEditMode, isGlobal, isDirty, isPlatinumPlus]); + const osOptions: Array<EuiSuperSelectOption<OperatingSystem>> = useMemo( () => OPERATING_SYSTEMS.map((os) => ({ value: os, inputDisplay: OS_TITLES[os] })), [] @@ -213,7 +234,7 @@ export const CreateTrustedAppForm = memo<CreateTrustedAppFormProps>( // We create local state for the list of policies because we want the selected policies to // persist while the user is on the form and possibly toggling between global/non-global const [selectedPolicies, setSelectedPolicies] = useState<EffectedPolicySelection>({ - isGlobal: isGlobalEffectScope(trustedApp.effectScope), + isGlobal, selected: [], }); @@ -406,7 +427,7 @@ export const CreateTrustedAppForm = memo<CreateTrustedAppFormProps>( }, [notifyOfChange, trustedApp]); // Anytime the TrustedApp has an effective scope of `policies`, then ensure that - // those polices are selected in the UI while at teh same time preserving prior + // those polices are selected in the UI while at the same time preserving prior // selections (UX requirement) useEffect(() => { setSelectedPolicies((currentSelection) => { @@ -530,12 +551,13 @@ export const CreateTrustedAppForm = memo<CreateTrustedAppFormProps>( data-test-subj={getTestId('conditionsBuilder')} /> </EuiFormRow> - {isTrustedAppsByPolicyEnabled ? ( + {isTrustedAppsByPolicyEnabled && !hideAssignmentSection ? ( <> <EuiHorizontalRule /> <EuiFormRow fullWidth={fullWidth} data-test-subj={getTestId('policySelection')}> <EffectedPolicySelect - isGlobal={isGlobalEffectScope(trustedApp.effectScope)} + isGlobal={isGlobal} + isPlatinumPlus={isPlatinumPlus} selected={selectedPolicies.selected} options={policies.options} onChange={handlePolicySelectChange} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.test.tsx index 4837a816d0ed8..3e48ccc6d9b6d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.test.tsx @@ -44,6 +44,7 @@ describe('when using EffectedPolicySelect component', () => { componentProps = { options: [], isGlobal: true, + isPlatinumPlus: true, onChange: handleOnChange, 'data-test-subj': 'test', }; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx index bb620ee5e7c01..e247602060384 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx @@ -56,12 +56,14 @@ export type EffectedPolicySelectProps = Omit< > & { options: PolicyData[]; isGlobal: boolean; + isPlatinumPlus: boolean; onChange: (selection: EffectedPolicySelection) => void; selected?: PolicyData[]; }; export const EffectedPolicySelect = memo<EffectedPolicySelectProps>( ({ isGlobal, + isPlatinumPlus, onChange, listProps, options, @@ -107,7 +109,8 @@ export const EffectedPolicySelect = memo<EffectedPolicySelectProps>( id={htmlIdGenerator()()} onChange={NOOP} checked={isPolicySelected.has(policy.id)} - disabled={isGlobal} + disabled={isGlobal || !isPlatinumPlus} + data-test-subj={`policy-${policy.id}-checkbox`} /> ), append: ( @@ -124,11 +127,11 @@ export const EffectedPolicySelect = memo<EffectedPolicySelectProps>( ), policy, checked: isPolicySelected.has(policy.id) ? 'on' : undefined, - disabled: isGlobal, + disabled: isGlobal || !isPlatinumPlus, 'data-test-subj': `policy-${policy.id}`, })) .sort(({ label: labelA }, { label: labelB }) => labelA.localeCompare(labelB)); - }, [getAppUrl, isGlobal, options, selected]); + }, [getAppUrl, isGlobal, isPlatinumPlus, options, selected]); const handleOnPolicySelectChange = useCallback< Required<EuiSelectableProps<OptionPolicyData>>['onChange'] @@ -178,7 +181,7 @@ export const EffectedPolicySelect = memo<EffectedPolicySelectProps>( <p> {i18n.translate('xpack.securitySolution.trustedApps.assignmentSectionDescription', { defaultMessage: - 'You can assign this trusted application globally across all policies or assign it to specific policies.', + 'Assign this trusted application globally across all policies, or assign it to specific policies.', })} </p> </EuiText> diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx index ba09d0c7ee0cc..6967c07db20b1 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx @@ -54,7 +54,7 @@ const RootWrapper = styled.div` const BACK_TO_TRUSTED_APPS_LABEL = i18n.translate( 'xpack.securitySolution.trustedapps.grid.policyDetailsLinkBackLabel', - { defaultMessage: 'Back to trusted Applications' } + { defaultMessage: 'Back to trusted applications' } ); const EDIT_TRUSTED_APP_ACTION_LABEL = i18n.translate( @@ -120,6 +120,12 @@ export const TrustedAppsGrid = memo(() => { ], href: getAppUrl({ path: currentPagePath }), }, + onCancelNavigateTo: [ + APP_ID, + { + path: currentPagePath, + }, + ], }; policyToNavOptionsMap[policyId] = { @@ -138,6 +144,7 @@ export const TrustedAppsGrid = memo(() => { cachedCardProps[trustedApp.id] = { item: trustedApp, policies, + hideComments: true, 'data-test-subj': 'trustedAppCard', actions: [ { diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx index 9e76cfd001c97..87c7439c236cc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx @@ -24,13 +24,7 @@ import { EuiText, } from '@elastic/eui'; -import { - Immutable, - ImmutableObject, - PolicyEffectScope, - GlobalEffectScope, - TrustedApp, -} from '../../../../../common/endpoint/types'; +import { Immutable, TrustedApp } from '../../../../../common/endpoint/types'; import { AppAction } from '../../../../common/store/actions'; import { useTrustedAppsSelector } from './hooks'; import { @@ -38,14 +32,10 @@ import { isDeletionDialogOpen, isDeletionInProgress, } from '../store/selectors'; +import { isPolicyEffectScope } from '../state/type_guards'; const CANCEL_SUBJ = 'trustedAppDeletionCancel'; const CONFIRM_SUBJ = 'trustedAppDeletionConfirm'; -const isTrustedAppByPolicy = ( - trustedApp: ImmutableObject<GlobalEffectScope | PolicyEffectScope> -): trustedApp is ImmutableObject<PolicyEffectScope> => { - return (trustedApp as ImmutableObject<PolicyEffectScope>).policies !== undefined; -}; const getTranslations = (entry: Immutable<TrustedApp> | undefined) => ({ title: ( @@ -67,7 +57,7 @@ const getTranslations = (entry: Immutable<TrustedApp> | undefined) => ({ defaultMessage="Deleting this entry will remove it from {count} associated {count, plural, one {policy} other {policies}}." values={{ count: - entry && isTrustedAppByPolicy(entry.effectScope) + entry && isPolicyEffectScope(entry.effectScope) ? entry.effectScope.policies.length : 'all', }} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx index faeef26032cd5..f39fd47c78771 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx @@ -34,15 +34,26 @@ import { forceHTMLElementOffsetWidth } from './components/effected_policy_select import { toUpdateTrustedApp } from '../../../../../common/endpoint/service/trusted_apps/to_update_trusted_app'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables'; - -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ - htmlIdGenerator: () => () => 'mockId', -})); +import { licenseService } from '../../../../common/hooks/use_license'; // TODO: remove this mock when feature flag is removed jest.mock('../../../../common/hooks/use_experimental_features'); const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock; +jest.mock('../../../../common/hooks/use_license', () => { + const licenseServiceInstance = { + isPlatinumPlus: jest.fn(), + }; + return { + licenseService: licenseServiceInstance, + useLicense: () => { + return licenseServiceInstance; + }, + }; +}); + +jest.mock('../../../../common/components/user_privileges/use_endpoint_privileges'); + describe('When on the Trusted Apps Page', () => { const expectedAboutInfo = 'Add a trusted application to improve performance or alleviate conflicts with other ' + @@ -58,26 +69,7 @@ describe('When on the Trusted Apps Page', () => { const originalScrollTo = window.scrollTo; const act = reactTestingLibrary.act; - const getFakeTrustedApp = (): TrustedApp => ({ - id: '1111-2222-3333-4444', - version: 'abc123', - name: 'one app', - os: OperatingSystem.WINDOWS, - created_at: '2021-01-04T13:55:00.561Z', - created_by: 'me', - updated_at: '2021-01-04T13:55:00.561Z', - updated_by: 'me', - description: 'a good one', - effectScope: { type: 'global' }, - entries: [ - { - field: ConditionEntryField.PATH, - value: 'one/two', - operator: 'included', - type: 'match', - }, - ], - }); + const getFakeTrustedApp = jest.fn(); const createListApiResponse = ( page: number = 1, @@ -137,9 +129,32 @@ describe('When on the Trusted Apps Page', () => { beforeEach(() => { mockedContext = createAppRootMockRenderer(); + getFakeTrustedApp.mockImplementation( + (): TrustedApp => ({ + id: '1111-2222-3333-4444', + version: 'abc123', + name: 'one app', + os: OperatingSystem.WINDOWS, + created_at: '2021-01-04T13:55:00.561Z', + created_by: 'me', + updated_at: '2021-01-04T13:55:00.561Z', + updated_by: 'me', + description: 'a good one', + effectScope: { type: 'global' }, + entries: [ + { + field: ConditionEntryField.PATH, + value: 'one/two', + operator: 'included', + type: 'match', + }, + ], + }) + ); history = mockedContext.history; coreStart = mockedContext.coreStart; + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); waitForAction = mockedContext.middlewareSpy.waitForAction; render = () => mockedContext.render(<TrustedAppsPage />); reactTestingLibrary.act(() => { @@ -178,19 +193,94 @@ describe('When on the Trusted Apps Page', () => { }); describe('and the Grid view is being displayed', () => { - describe('and the edit trusted app button is clicked', () => { - let renderResult: ReturnType<AppContextTestRender['render']>; + let renderResult: ReturnType<AppContextTestRender['render']>; + + const renderWithListDataAndClickOnEditCard = async () => { + renderResult = await renderWithListData(); + + await act(async () => { + (await renderResult.findAllByTestId('trustedAppCard-header-actions-button'))[0].click(); + }); + + act(() => { + fireEvent.click(renderResult.getByTestId('editTrustedAppAction')); + }); + }; + + const renderWithListDataAndClickAddButton = async (): Promise< + ReturnType<AppContextTestRender['render']> + > => { + renderResult = await renderWithListData(); + + act(() => { + const addButton = renderResult.getByTestId('trustedAppsListAddButton'); + fireEvent.click(addButton, { button: 1 }); + }); + + // Wait for the policies to be loaded + await act(async () => { + await waitForAction('trustedAppsPoliciesStateChanged', { + validate: (action) => { + return isLoadedResourceState(action.payload); + }, + }); + }); + return renderResult; + }; + + describe('the license is downgraded to gold or below and the user is editing a per policy TA', () => { beforeEach(async () => { - renderResult = await renderWithListData(); + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); + useIsExperimentalFeatureEnabledMock.mockReturnValue(true); - await act(async () => { - (await renderResult.findAllByTestId('trustedAppCard-header-actions-button'))[0].click(); + const originalFakeTrustedAppProvider = getFakeTrustedApp.getMockImplementation(); + getFakeTrustedApp.mockImplementation(() => { + return { + ...originalFakeTrustedAppProvider!(), + effectScope: { + type: 'policy', + policies: ['abc123'], + }, + }; }); + await renderWithListDataAndClickOnEditCard(); + }); + + it('shows a message at the top of the flyout to inform the user their license is expired', () => { + expect( + renderResult.queryByTestId('addTrustedAppFlyout-expired-license-callout') + ).toBeTruthy(); + }); + }); + + describe('the license is downgraded to gold or below and the user is adding a new TA', () => { + beforeEach(async () => { + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); + useIsExperimentalFeatureEnabledMock.mockReturnValue(true); - act(() => { - fireEvent.click(renderResult.getByTestId('editTrustedAppAction')); + const originalFakeTrustedAppProvider = getFakeTrustedApp.getMockImplementation(); + getFakeTrustedApp.mockImplementation(() => { + return { + ...originalFakeTrustedAppProvider!(), + effectScope: { + type: 'policy', + policies: ['abc123'], + }, + }; }); + await renderWithListDataAndClickAddButton(); + }); + it('does not show the expired license message at the top of the flyout', async () => { + expect( + renderResult.queryByTestId('addTrustedAppFlyout-expired-license-callout') + ).toBeNull(); + }); + }); + + describe('and the edit trusted app button is clicked', () => { + beforeEach(async () => { + await renderWithListDataAndClickOnEditCard(); }); it('should persist edit params to url', () => { @@ -281,7 +371,7 @@ describe('When on the Trusted Apps Page', () => { } ); - const renderResult = await renderWithListData(); + renderResult = await renderWithListData(); await reactTestingLibrary.act(async () => { await apiResponseForEditTrustedApp; @@ -314,7 +404,7 @@ describe('When on the Trusted Apps Page', () => { }); it('should retrieve trusted app via API using url `id`', async () => { - const renderResult = await renderAndWaitForGetApi(); + renderResult = await renderAndWaitForGetApi(); expect(coreStart.http.get).toHaveBeenCalledWith(TRUSTED_APP_GET_URI); diff --git a/x-pack/plugins/security_solution/public/network/components/port/helpers.ts b/x-pack/plugins/security_solution/public/network/components/port/helpers.ts new file mode 100644 index 0000000000000..e162fb3f90968 --- /dev/null +++ b/x-pack/plugins/security_solution/public/network/components/port/helpers.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export const CLIENT_PORT_FIELD_NAME = 'client.port'; +export const DESTINATION_PORT_FIELD_NAME = 'destination.port'; +export const SERVER_PORT_FIELD_NAME = 'server.port'; +export const SOURCE_PORT_FIELD_NAME = 'source.port'; +export const URL_PORT_FIELD_NAME = 'url.port'; + +export const PORT_NAMES = [ + CLIENT_PORT_FIELD_NAME, + DESTINATION_PORT_FIELD_NAME, + SERVER_PORT_FIELD_NAME, + SOURCE_PORT_FIELD_NAME, + URL_PORT_FIELD_NAME, +]; diff --git a/x-pack/plugins/security_solution/public/network/components/port/index.tsx b/x-pack/plugins/security_solution/public/network/components/port/index.tsx index 4afd9bc7b892a..769aa7300d138 100644 --- a/x-pack/plugins/security_solution/public/network/components/port/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/port/index.tsx @@ -5,33 +5,22 @@ * 2.0. */ +import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import React from 'react'; import { DefaultDraggable } from '../../../common/components/draggables'; import { getEmptyValue } from '../../../common/components/empty_value'; import { PortOrServiceNameLink } from '../../../common/components/links'; -export const CLIENT_PORT_FIELD_NAME = 'client.port'; -export const DESTINATION_PORT_FIELD_NAME = 'destination.port'; -export const SERVER_PORT_FIELD_NAME = 'server.port'; -export const SOURCE_PORT_FIELD_NAME = 'source.port'; -export const URL_PORT_FIELD_NAME = 'url.port'; - -export const PORT_NAMES = [ - CLIENT_PORT_FIELD_NAME, - DESTINATION_PORT_FIELD_NAME, - SERVER_PORT_FIELD_NAME, - SOURCE_PORT_FIELD_NAME, - URL_PORT_FIELD_NAME, -]; - export const Port = React.memo<{ contextId: string; + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; eventId: string; fieldName: string; isDraggable?: boolean; + title?: string; value: string | undefined | null; -}>(({ contextId, eventId, fieldName, isDraggable, value }) => +}>(({ Component, contextId, eventId, fieldName, isDraggable, title, value }) => isDraggable ? ( <DefaultDraggable data-test-subj="port" @@ -41,10 +30,18 @@ export const Port = React.memo<{ tooltipContent={fieldName} value={value} > - <PortOrServiceNameLink portOrServiceName={value || getEmptyValue()} /> + <PortOrServiceNameLink + portOrServiceName={value || getEmptyValue()} + Component={Component} + title={title} + /> </DefaultDraggable> ) : ( - <PortOrServiceNameLink portOrServiceName={value || getEmptyValue()} /> + <PortOrServiceNameLink + portOrServiceName={value || getEmptyValue()} + Component={Component} + title={title} + /> ) ); diff --git a/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx index 3da5ec6d4b218..3332111d14f8b 100644 --- a/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx @@ -18,7 +18,7 @@ import { TestProviders } from '../../../common/mock/test_providers'; import { ID_FIELD_NAME } from '../../../common/components/event_details/event_id'; import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip'; -import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME } from '../port'; +import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME } from '../port/helpers'; import { DESTINATION_BYTES_FIELD_NAME, DESTINATION_PACKETS_FIELD_NAME, diff --git a/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx b/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx index 824b9fd11f242..f16cd7dbb109f 100644 --- a/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx @@ -15,7 +15,7 @@ import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock/test_providers'; import { ID_FIELD_NAME } from '../../../common/components/event_details/event_id'; import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip'; -import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME } from '../port'; +import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME } from '../port/helpers'; import * as i18n from '../../../timelines/components/timeline/body/renderers/translations'; import { useMountAppended } from '../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.tsx b/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.tsx index 31bae6880fcbe..2be1c5f50406f 100644 --- a/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.tsx +++ b/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.tsx @@ -11,7 +11,8 @@ import React from 'react'; import deepEqual from 'fast-deep-equal'; import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip'; -import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME, Port } from '../port'; +import { Port } from '../port'; +import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME } from '../port/helpers'; import * as i18n from '../../../timelines/components/timeline/body/renderers/translations'; import { GeoFields } from './geo_fields'; diff --git a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx index 5cea3fa98eeb7..7de1d9d9f40c1 100644 --- a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx @@ -49,8 +49,10 @@ interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery' | 'se indexPattern: IIndexPattern; indexNames: string[]; onlyField?: string; + paddingSize?: 's' | 'm' | 'l' | 'none'; query: Query; setAbsoluteRangeDatePickerTarget?: InputsModelId; + showLegend?: boolean; showSpacer?: boolean; timelineId?: string; toggleTopN?: () => void; @@ -70,9 +72,11 @@ const EventsByDatasetComponent: React.FC<Props> = ({ indexPattern, indexNames, onlyField, + paddingSize, query, setAbsoluteRangeDatePickerTarget, setQuery, + showLegend, showSpacer = true, timelineId, to, @@ -177,9 +181,11 @@ const EventsByDatasetComponent: React.FC<Props> = ({ id={uniqueQueryId} indexNames={indexNames} onError={toggleTopN} + paddingSize={paddingSize} setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget} setQuery={setQuery} showSpacer={showSpacer} + showLegend={showLegend} skip={filterQuery === undefined} startDate={from} timelineId={timelineId} diff --git a/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx b/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx index 76116f2261118..321e6d00b5301 100644 --- a/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx @@ -23,8 +23,10 @@ interface Props { headerChildren?: React.ReactNode; /** Override all defaults, and only display this field */ onlyField?: AlertsStackByField; + paddingSize?: 's' | 'm' | 'l' | 'none'; query?: Query; setAbsoluteRangeDatePickerTarget?: InputsModelId; + showLegend?: boolean; timelineId?: string; } @@ -33,7 +35,9 @@ const SignalsByCategoryComponent: React.FC<Props> = ({ filters, headerChildren, onlyField, + paddingSize, query, + showLegend, setAbsoluteRangeDatePickerTarget = 'global', timelineId, }) => { @@ -61,16 +65,18 @@ const SignalsByCategoryComponent: React.FC<Props> = ({ combinedQueries={combinedQueries} filters={filters} headerChildren={headerChildren} + legendPosition={'right'} onlyField={onlyField} - titleSize={onlyField == null ? 'm' : 's'} + paddingSize={paddingSize} query={query} - signalIndexName={signalIndexName} - showTotalAlertsCount={true} + showLegend={showLegend} showLinkToAlerts={onlyField == null ? true : false} showStackBy={onlyField == null} - legendPosition={'right'} + showTotalAlertsCount={true} + signalIndexName={signalIndexName} timelineId={timelineId} title={i18n.ALERT_COUNT} + titleSize={onlyField == null ? 'm' : 's'} updateDateRange={updateDateRangeCallback} /> ); diff --git a/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_hosts_risk_score.ts b/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_hosts_risk_score.ts index af663bb74f54a..15cb7ef7b1c46 100644 --- a/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_hosts_risk_score.ts +++ b/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_hosts_risk_score.ts @@ -98,7 +98,7 @@ export const useHostsRiskScore = ({ useEffect(() => { if (riskyHostsFeatureEnabled && (hostName || timerange)) { - spaces.getActiveSpace().then((space) => { + spaces?.getActiveSpace().then((space) => { start({ data, timerange: timerange diff --git a/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx index 913a0f7ed200b..e1f0954683e04 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx @@ -10,6 +10,7 @@ import React, { useCallback, useMemo, useContext } from 'react'; import { useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; +import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import { FlowTarget } from '../../../../common/search_strategy/security_solution/network'; import { DragEffects, @@ -145,11 +146,15 @@ interface AddressLinksItemProps extends Omit<AddressLinksProps, 'addresses'> { const AddressLinksItemComponent: React.FC<AddressLinksItemProps> = ({ address, + Component, contextId, eventId, fieldName, + isButton, isDraggable, + onClick, truncate, + title, }) => { const key = `address-links-draggable-wrapper-${getUniqueId({ contextId, @@ -171,6 +176,10 @@ const AddressLinksItemComponent: React.FC<AddressLinksItemProps> = ({ const openNetworkDetailsSidePanel = useCallback( (e) => { e.preventDefault(); + if (onClick) { + onClick(); + } + if (eventContext && isInTimelineContext) { const { tabType, timelineID } = eventContext; const updatedExpandedDetail: TimelineExpandedDetailType = { @@ -196,22 +205,41 @@ const AddressLinksItemComponent: React.FC<AddressLinksItemProps> = ({ } } }, - [eventContext, isInTimelineContext, address, fieldName, dispatch] + [onClick, eventContext, isInTimelineContext, address, fieldName, dispatch] ); // The below is explicitly defined this way as the onClick takes precedence when it and the href are both defined // When this component is used outside of timeline/alerts table (i.e. in the flyout) we would still like it to link to the IP Overview page const content = useMemo( - () => ( - <Content field={fieldName} tooltipContent={fieldName}> + () => + Component ? ( <NetworkDetailsLink + Component={Component} ip={address} - isButton={false} + isButton={isButton} onClick={isInTimelineContext ? openNetworkDetailsSidePanel : undefined} + title={title} /> - </Content> - ), - [address, fieldName, isInTimelineContext, openNetworkDetailsSidePanel] + ) : ( + <Content field={fieldName} tooltipContent={fieldName}> + <NetworkDetailsLink + Component={Component} + ip={address} + isButton={isButton} + onClick={isInTimelineContext ? openNetworkDetailsSidePanel : undefined} + title={title} + /> + </Content> + ), + [ + Component, + address, + fieldName, + isButton, + isInTimelineContext, + openNetworkDetailsSidePanel, + title, + ] ); const render = useCallback( @@ -245,20 +273,28 @@ const AddressLinksItem = React.memo(AddressLinksItemComponent); interface AddressLinksProps { addresses: string[]; + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; contextId: string; eventId: string; fieldName: string; + isButton?: boolean; isDraggable: boolean; + onClick?: () => void; truncate?: boolean; + title?: string; } const AddressLinksComponent: React.FC<AddressLinksProps> = ({ addresses, + Component, contextId, eventId, fieldName, + isButton, isDraggable, + onClick, truncate, + title, }) => { const uniqAddresses = useMemo(() => uniq(addresses), [addresses]); @@ -268,14 +304,29 @@ const AddressLinksComponent: React.FC<AddressLinksProps> = ({ <AddressLinksItem key={address} address={address} + Component={Component} contextId={contextId} eventId={eventId} fieldName={fieldName} + isButton={isButton} isDraggable={isDraggable} + onClick={onClick} truncate={truncate} + title={title} /> )), - [contextId, eventId, fieldName, isDraggable, truncate, uniqAddresses] + [ + Component, + contextId, + eventId, + fieldName, + isButton, + isDraggable, + onClick, + title, + truncate, + uniqAddresses, + ] ); return <>{content}</>; @@ -293,13 +344,28 @@ const AddressLinks = React.memo( ); const FormattedIpComponent: React.FC<{ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; contextId: string; eventId: string; fieldName: string; + isButton?: boolean; isDraggable: boolean; + onClick?: () => void; + title?: string; truncate?: boolean; value: string | object | null | undefined; -}> = ({ contextId, eventId, fieldName, isDraggable, truncate, value }) => { +}> = ({ + Component, + contextId, + eventId, + fieldName, + isDraggable, + isButton, + onClick, + title, + truncate, + value, +}) => { if (isString(value) && !isEmpty(value)) { try { const addresses = JSON.parse(value); @@ -307,10 +373,14 @@ const FormattedIpComponent: React.FC<{ return ( <AddressLinks addresses={addresses} + Component={Component} contextId={contextId} eventId={eventId} fieldName={fieldName} + isButton={isButton} isDraggable={isDraggable} + onClick={onClick} + title={title} truncate={truncate} /> ); @@ -323,11 +393,15 @@ const FormattedIpComponent: React.FC<{ return ( <AddressLinks addresses={[value]} + Component={Component} contextId={contextId} eventId={eventId} + isButton={isButton} isDraggable={isDraggable} + onClick={onClick} fieldName={fieldName} truncate={truncate} + title={title} /> ); } else { diff --git a/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx index 5392b382d6c82..23a52b878472f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx @@ -25,7 +25,7 @@ import { JA3_HASH_FIELD_NAME } from '../ja3_fingerprint'; import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME, -} from '../../../network/components/port'; +} from '../../../network/components/port/helpers'; import { DESTINATION_GEO_CITY_NAME_FIELD_NAME, DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/column_renderer.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/column_renderer.ts index 1e6f613999ece..0ec974f876894 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/column_renderer.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/column_renderer.ts @@ -6,33 +6,44 @@ */ import type React from 'react'; +import { Filter } from '../../../../../../../../../src/plugins/data/public'; +import { BrowserFields } from '../../../../../../../timelines/common/search_strategy'; -import { BrowserFields, ColumnHeaderOptions, RowRenderer } from '../../../../../../common'; +import { ColumnHeaderOptions, RowRenderer } from '../../../../../../common'; import { Ecs } from '../../../../../../common/ecs'; import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline'; export interface ColumnRenderer { isInstance: (columnName: string, data: TimelineNonEcsData[]) => boolean; renderColumn: ({ + browserFields, + className, columnName, eventId, field, + globalFilters, + isDetails, isDraggable, + linkValues, + rowRenderers, timelineId, truncate, values, - linkValues, }: { + asPlainText?: boolean; + browserFields?: BrowserFields; + className?: string; columnName: string; + ecsData?: Ecs; eventId: string; field: ColumnHeaderOptions; + globalFilters?: Filter[]; + isDetails?: boolean; isDraggable?: boolean; + linkValues?: string[] | null | undefined; + rowRenderers?: RowRenderer[]; timelineId: string; truncate?: boolean; values: string[] | null | undefined; - linkValues?: string[] | null | undefined; - ecsData?: Ecs; - rowRenderers?: RowRenderer[]; - browserFields?: BrowserFields; }) => React.ReactNode; } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx index 5eec4ef66f39c..63e7e164854df 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx @@ -7,7 +7,7 @@ /* eslint-disable complexity */ -import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { EuiButtonEmpty, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { isNumber, isEmpty } from 'lodash/fp'; import React from 'react'; @@ -19,7 +19,8 @@ import { getOrEmptyTagFromValue } from '../../../../../common/components/empty_v import { FormattedDate } from '../../../../../common/components/formatted_date'; import { FormattedIp } from '../../../../components/formatted_ip'; -import { Port, PORT_NAMES } from '../../../../../network/components/port'; +import { Port } from '../../../../../network/components/port'; +import { PORT_NAMES } from '../../../../../network/components/port/helpers'; import { TruncatableText } from '../../../../../common/components/truncatable_text'; import { DATE_FIELD_TYPE, @@ -44,44 +45,60 @@ import { AgentStatuses } from './agent_statuses'; const columnNamesNotDraggable = [MESSAGE_FIELD_NAME]; const FormattedFieldValueComponent: React.FC<{ + asPlainText?: boolean; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; contextId: string; eventId: string; isObjectArray?: boolean; fieldFormat?: string; fieldName: string; fieldType?: string; + isButton?: boolean; isDraggable?: boolean; + onClick?: () => void; + title?: string; truncate?: boolean; value: string | number | undefined | null; linkValue?: string | null | undefined; }> = ({ + asPlainText, + Component, contextId, eventId, fieldFormat, fieldName, fieldType, + isButton, isObjectArray = false, isDraggable = true, - truncate, + onClick, + title, + truncate = true, value, linkValue, }) => { - if (isObjectArray) { - return <>{value}</>; + if (isObjectArray || asPlainText) { + return <span data-test-subj={`formatted-field-${fieldName}`}>{value}</span>; } else if (fieldType === IP_FIELD_TYPE) { return ( <FormattedIp + Component={Component} eventId={eventId} contextId={contextId} fieldName={fieldName} + isButton={isButton} isDraggable={isDraggable} value={!isNumber(value) ? value : String(value)} + onClick={onClick} + title={title} truncate={truncate} /> ); } else if (fieldType === GEO_FIELD_TYPE) { return <>{value}</>; } else if (fieldType === DATE_FIELD_TYPE) { + const classNames = truncate ? 'eui-textTruncate eui-alignMiddle' : undefined; return isDraggable ? ( <DefaultDraggable field={fieldName} @@ -90,18 +107,20 @@ const FormattedFieldValueComponent: React.FC<{ tooltipContent={null} value={`${value}`} > - <FormattedDate fieldName={fieldName} value={value} /> + <FormattedDate className={classNames} fieldName={fieldName} value={value} /> </DefaultDraggable> ) : ( - <FormattedDate fieldName={fieldName} value={value} /> + <FormattedDate className={classNames} fieldName={fieldName} value={value} /> ); } else if (PORT_NAMES.some((portName) => fieldName === portName)) { return ( <Port + Component={Component} contextId={contextId} eventId={eventId} fieldName={fieldName} isDraggable={isDraggable} + title={title} value={`${value}`} /> ); @@ -118,10 +137,14 @@ const FormattedFieldValueComponent: React.FC<{ } else if (fieldName === HOST_NAME_FIELD_NAME) { return ( <HostName + Component={Component} contextId={contextId} eventId={eventId} fieldName={fieldName} isDraggable={isDraggable} + isButton={isButton} + onClick={onClick} + title={title} value={value} /> ); @@ -138,11 +161,13 @@ const FormattedFieldValueComponent: React.FC<{ } else if (fieldName === SIGNAL_RULE_NAME_FIELD_NAME) { return ( <RenderRuleName + Component={Component} contextId={contextId} eventId={eventId} fieldName={fieldName} isDraggable={isDraggable} linkValue={linkValue} + title={title} truncate={truncate} value={value} /> @@ -185,7 +210,17 @@ const FormattedFieldValueComponent: React.FC<{ INDICATOR_REFERENCE, ].includes(fieldName) ) { - return renderUrl({ contextId, eventId, fieldName, linkValue, isDraggable, truncate, value }); + return renderUrl({ + contextId, + Component, + eventId, + fieldName, + linkValue, + isDraggable, + truncate, + title, + value, + }); } else if (columnNamesNotDraggable.includes(fieldName) || !isDraggable) { return truncate && !isEmpty(value) ? ( <TruncatableText data-test-subj="truncatable-message"> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx index 3343882e0071a..cda196fd79634 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx @@ -5,9 +5,17 @@ * 2.0. */ -import { EuiLink, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiToolTip } from '@elastic/eui'; +import { + EuiButtonEmpty, + EuiButtonIcon, + EuiLink, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiToolTip, +} from '@elastic/eui'; import { isString, isEmpty } from 'lodash/fp'; -import React, { useCallback } from 'react'; +import React, { SyntheticEvent, useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { DefaultDraggable } from '../../../../../common/components/draggables'; @@ -30,22 +38,26 @@ const EventModuleFlexItem = styled(EuiFlexItem)` `; interface RenderRuleNameProps { + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; contextId: string; eventId: string; fieldName: string; isDraggable: boolean; linkValue: string | null | undefined; truncate?: boolean; + title?: string; value: string | number | null | undefined; } export const RenderRuleName: React.FC<RenderRuleNameProps> = ({ + Component, contextId, eventId, fieldName, isDraggable, linkValue, truncate, + title, value, }) => { const ruleName = `${value}`; @@ -69,15 +81,29 @@ export const RenderRuleName: React.FC<RenderRuleNameProps> = ({ [navigateToApp, ruleId, search] ); + const href = useMemo( + () => + getUrlForApp(APP_ID, { + deepLinkId: SecurityPageName.rules, + path: getRuleDetailsUrl(ruleId ?? '', search), + }), + [getUrlForApp, ruleId, search] + ); + const id = `event-details-value-default-draggable-${contextId}-${eventId}-${fieldName}-${value}-${ruleId}`; + if (isString(value) && ruleName.length > 0 && ruleId != null) { - const link = ( - <LinkAnchor + const link = Component ? ( + <Component + aria-label={title} + data-test-subj={`view-${fieldName}`} + iconType="link" onClick={goToRuleDetails} - href={getUrlForApp(APP_ID, { - deepLinkId: SecurityPageName.rules, - path: getRuleDetailsUrl(ruleId, search), - })} + title={title} > + {title ?? value} + </Component> + ) : ( + <LinkAnchor onClick={goToRuleDetails} href={href}> {content} </LinkAnchor> ); @@ -85,7 +111,7 @@ export const RenderRuleName: React.FC<RenderRuleNameProps> = ({ return isDraggable ? ( <DefaultDraggable field={fieldName} - id={`event-details-value-default-draggable-${contextId}-${eventId}-${fieldName}-${value}-${ruleId}`} + id={id} isDraggable={isDraggable} tooltipContent={value} value={value} @@ -99,7 +125,7 @@ export const RenderRuleName: React.FC<RenderRuleNameProps> = ({ return isDraggable ? ( <DefaultDraggable field={fieldName} - id={`event-details-value-default-draggable-${contextId}-${eventId}-${fieldName}-${value}-${ruleId}`} + id={id} isDraggable={isDraggable} tooltipContent={value} value={`${value}`} @@ -189,35 +215,71 @@ export const renderEventModule = ({ ); }; +const GenericLinkComponent: React.FC<{ + children?: React.ReactNode; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; + dataTestSubj?: string; + href: string; + onClick?: (e: SyntheticEvent) => void; + title?: string; + iconType?: string; +}> = ({ children, Component, dataTestSubj, href, onClick, title, iconType = 'link' }) => { + return Component ? ( + <Component + data-test-subj={dataTestSubj} + href={href} + iconType={iconType} + onClick={onClick} + title={title} + > + {title ?? children} + </Component> + ) : ( + <EuiLink data-test-subj={dataTestSubj} target="_blank" href={href}> + {title ?? children} + </EuiLink> + ); +}; + +const GenericLink = React.memo(GenericLinkComponent); + export const renderUrl = ({ contextId, + Component, eventId, fieldName, isDraggable, linkValue, truncate, + title, value, }: { contextId: string; + /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; eventId: string; fieldName: string; isDraggable: boolean; linkValue: string | null | undefined; truncate?: boolean; + title?: string; value: string | number | null | undefined; }) => { const urlName = `${value}`; + const isUrlValid = !isUrlInvalid(urlName); const formattedValue = truncate ? <TruncatableText>{value}</TruncatableText> : value; - const content = ( - <> - {!isUrlInvalid(urlName) && ( - <EuiLink target="_blank" href={urlName}> - {formattedValue} - </EuiLink> - )} - {isUrlInvalid(urlName) && <>{formattedValue}</>} - </> + const content = isUrlValid ? ( + <GenericLink + Component={Component} + href={urlName} + dataTestSubj="ata-grid-url" + title={title} + iconType="link" + /> + ) : ( + <>{formattedValue}</> ); return isString(value) && urlName.length > 0 ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx index c183d71212540..5864e144a681e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback, useContext, useMemo } from 'react'; +import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import { useDispatch } from 'react-redux'; import { isString } from 'lodash/fp'; import { HostDetailsLink } from '../../../../../common/components/links'; @@ -23,17 +24,25 @@ import { StatefulEventContext } from '../../../../../../../timelines/public'; interface Props { contextId: string; + Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; eventId: string; fieldName: string; isDraggable: boolean; + isButton?: boolean; + onClick?: () => void; value: string | number | undefined | null; + title?: string; } const HostNameComponent: React.FC<Props> = ({ fieldName, + Component, contextId, eventId, isDraggable, + isButton, + onClick, + title, value, }) => { const dispatch = useDispatch(); @@ -44,6 +53,10 @@ const HostNameComponent: React.FC<Props> = ({ const openHostDetailsSidePanel = useCallback( (e) => { e.preventDefault(); + + if (onClick) { + onClick(); + } if (eventContext && isInTimelineContext) { const { timelineID, tabType } = eventContext; const updatedExpandedDetail: TimelineExpandedDetailType = { @@ -66,7 +79,7 @@ const HostNameComponent: React.FC<Props> = ({ } } }, - [dispatch, eventContext, isInTimelineContext, hostName] + [onClick, eventContext, isInTimelineContext, hostName, dispatch] ); // The below is explicitly defined this way as the onClick takes precedence when it and the href are both defined @@ -74,14 +87,16 @@ const HostNameComponent: React.FC<Props> = ({ const content = useMemo( () => ( <HostDetailsLink + Component={Component} hostName={hostName} - isButton={false} + isButton={isButton} onClick={isInTimelineContext ? openHostDetailsSidePanel : undefined} + title={title} > <TruncatableText data-test-subj="draggable-truncatable-content">{hostName}</TruncatableText> </HostDetailsLink> ), - [hostName, isInTimelineContext, openHostDetailsSidePanel] + [Component, hostName, isButton, isInTimelineContext, openHostDetailsSidePanel, title] ); return isString(value) && hostName.length > 0 ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow.tsx index d6ea939c966ac..acc88ef3ee111 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow.tsx @@ -29,7 +29,7 @@ import { import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME, -} from '../../../../../network/components/port'; +} from '../../../../../network/components/port/helpers'; import { DESTINATION_GEO_CITY_NAME_FIELD_NAME, DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.tsx index f38304e718675..e36e347fc0cc3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.tsx @@ -34,7 +34,7 @@ import { import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME, -} from '../../../../../../network/components/port'; +} from '../../../../../../network/components/port/helpers'; import { NETWORK_BYTES_FIELD_NAME, NETWORK_COMMUNITY_ID_FIELD_NAME, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.tsx index 8509e7be0d22b..2f0653826d11b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.tsx @@ -7,6 +7,7 @@ import { head } from 'lodash/fp'; import React from 'react'; +import { Filter } from '../../../../../../../../../src/plugins/data/public'; import { ColumnHeaderOptions } from '../../../../../../common'; import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline'; @@ -21,8 +22,8 @@ export const dataExistsAtColumn = (columnName: string, data: TimelineNonEcsData[ export const plainColumnRenderer: ColumnRenderer = { isInstance: (columnName: string, data: TimelineNonEcsData[]) => dataExistsAtColumn(columnName, data), - renderColumn: ({ + asPlainText, columnName, eventId, field, @@ -32,9 +33,11 @@ export const plainColumnRenderer: ColumnRenderer = { values, linkValues, }: { + asPlainText?: boolean; columnName: string; eventId: string; field: ColumnHeaderOptions; + globalFilters?: Filter[]; isDraggable?: boolean; timelineId: string; truncate?: boolean; @@ -44,16 +47,17 @@ export const plainColumnRenderer: ColumnRenderer = { values != null ? values.map((value, i) => ( <FormattedFieldValue - key={`plain-column-renderer-formatted-field-value-${timelineId}-${columnName}-${eventId}-${field.id}-${value}-${i}`} + asPlainText={asPlainText} contextId={`plain-column-renderer-formatted-field-value-${timelineId}`} eventId={eventId} fieldFormat={field.format || ''} fieldName={columnName} fieldType={field.type || ''} isDraggable={isDraggable} - value={parseValue(value)} - truncate={truncate} + key={`plain-column-renderer-formatted-field-value-${timelineId}-${columnName}-${eventId}-${field.id}-${value}-${i}`} linkValue={head(linkValues)} + truncate={truncate} + value={parseValue(value)} /> )) : getEmptyTagValue(), diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.test.tsx index 9d711b9593622..8fdd6483a14f8 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.test.tsx @@ -19,7 +19,7 @@ import { RowRenderer, RowRendererId, } from '../../../../../../common'; -import { fireEvent, render } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { TestProviders } from '../../../../../../../timelines/public/mock'; import { useDraggableKeyboardWrapper as mockUseDraggableKeyboardWrapper } from '../../../../../../../timelines/public/components'; import { cloneDeep } from 'lodash'; @@ -92,9 +92,10 @@ describe('reasonColumnRenderer', () => { expect(plainColumnRenderer.renderColumn).toBeCalledTimes(1); }); - it("doesn't call `plainColumnRenderer.renderColumn` when ecsData, rowRenderers or browserFields fields are not empty", () => { + it("doesn't call `plainColumnRenderer.renderColumn` in expanded value when ecsData, rowRenderers or browserFields fields are not empty", () => { reasonColumnRenderer.renderColumn({ ...defaultProps, + isDetails: true, ecsData: invalidEcs, rowRenderers, browserFields, @@ -103,50 +104,36 @@ describe('reasonColumnRenderer', () => { expect(plainColumnRenderer.renderColumn).toBeCalledTimes(0); }); - it("doesn't render popover button when getRowRenderer doesn't find a rowRenderer", () => { - const renderedColumn = reasonColumnRenderer.renderColumn({ + it('call `plainColumnRenderer.renderColumn` in cell value', () => { + reasonColumnRenderer.renderColumn({ ...defaultProps, + isDetails: false, ecsData: invalidEcs, rowRenderers, browserFields, }); - const wrapper = render(<TestProviders>{renderedColumn}</TestProviders>); - - expect(wrapper.queryByTestId('reason-cell-button')).not.toBeInTheDocument(); - }); - - it('render popover button when getRowRenderer finds a rowRenderer', () => { - const renderedColumn = reasonColumnRenderer.renderColumn({ - ...defaultProps, - ecsData: validEcs, - rowRenderers, - browserFields, - }); - - const wrapper = render(<TestProviders>{renderedColumn}</TestProviders>); - - expect(wrapper.queryByTestId('reason-cell-button')).toBeInTheDocument(); + expect(plainColumnRenderer.renderColumn).toBeCalledTimes(1); }); - it('render rowRender inside a popover when reson field button is clicked', () => { + it("doesn't render reason renderers button when getRowRenderer doesn't find a rowRenderer", () => { const renderedColumn = reasonColumnRenderer.renderColumn({ ...defaultProps, - ecsData: validEcs, + isDetails: true, + ecsData: invalidEcs, rowRenderers, browserFields, }); const wrapper = render(<TestProviders>{renderedColumn}</TestProviders>); - fireEvent.click(wrapper.getByTestId('reason-cell-button')); - - expect(wrapper.queryByTestId('test-row-render')).toBeInTheDocument(); + expect(wrapper.queryByTestId('reason-cell-button')).not.toBeInTheDocument(); }); - it('the popover always contains a class that hides it when an overlay (e.g. the inspect modal) is displayed', () => { + it('render reason renderers when getRowRenderer finds a rowRenderer', () => { const renderedColumn = reasonColumnRenderer.renderColumn({ ...defaultProps, + isDetails: true, ecsData: validEcs, rowRenderers, browserFields, @@ -154,11 +141,7 @@ describe('reasonColumnRenderer', () => { const wrapper = render(<TestProviders>{renderedColumn}</TestProviders>); - fireEvent.click(wrapper.getByTestId('reason-cell-button')); - - expect(wrapper.getByRole('dialog')).toHaveClass( - 'euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--noShadow euiPopover__panel euiPopover__panel--right withHoverActions__popover' - ); + expect(wrapper.queryByTestId('reason-cell-renderer')).toBeInTheDocument(); }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.tsx index 52483b4853cbc..b3f145beb886b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/reason_column_renderer.tsx @@ -5,11 +5,10 @@ * 2.0. */ -import { EuiButtonEmpty, EuiPopover, EuiPopoverTitle } from '@elastic/eui'; +import { EuiSpacer, EuiPanel } from '@elastic/eui'; import { isEqual } from 'lodash/fp'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useMemo } from 'react'; -import styled from 'styled-components'; import { BrowserFields, ColumnHeaderOptions, RowRenderer } from '../../../../../../common'; import { Ecs } from '../../../../../../common/ecs'; import { eventRendererNames } from '../../../row_renderers_browser/catalog/constants'; @@ -23,58 +22,59 @@ export const reasonColumnRenderer: ColumnRenderer = { isInstance: isEqual(REASON_FIELD_NAME), renderColumn: ({ + browserFields, columnName, + ecsData, eventId, field, + isDetails, isDraggable = true, + linkValues, + rowRenderers = [], timelineId, truncate, values, - linkValues, - ecsData, - rowRenderers = [], - browserFields, }: { + browserFields?: BrowserFields; columnName: string; + ecsData?: Ecs; eventId: string; field: ColumnHeaderOptions; + isDetails?: boolean; isDraggable?: boolean; + linkValues?: string[] | null | undefined; + rowRenderers?: RowRenderer[]; timelineId: string; truncate?: boolean; values: string[] | undefined | null; - linkValues?: string[] | null | undefined; - - ecsData?: Ecs; - rowRenderers?: RowRenderer[]; - browserFields?: BrowserFields; - }) => - values != null && ecsData && rowRenderers?.length > 0 && browserFields - ? values.map((value, i) => ( - <ReasonCell - key={`reason-column-renderer-value-${timelineId}-${columnName}-${eventId}-${field.id}-${value}-${i}`} - timelineId={timelineId} - value={value} - ecsData={ecsData} - rowRenderers={rowRenderers} - browserFields={browserFields} - /> - )) - : plainColumnRenderer.renderColumn({ - columnName, - eventId, - field, - isDraggable, - timelineId, - truncate, - values, - linkValues, - }), + }) => { + if (isDetails && values && ecsData && rowRenderers && browserFields) { + return values.map((value, i) => ( + <ReasonCell + browserFields={browserFields} + ecsData={ecsData} + key={`reason-column-renderer-value-${timelineId}-${columnName}-${eventId}-${field.id}-${value}-${i}`} + rowRenderers={rowRenderers} + timelineId={timelineId} + value={value} + /> + )); + } else { + return plainColumnRenderer.renderColumn({ + columnName, + eventId, + field, + isDetails, + isDraggable, + linkValues, + timelineId, + truncate, + values, + }); + } + }, }; -const StyledEuiButtonEmpty = styled(EuiButtonEmpty)` - font-weight: ${(props) => props.theme.eui.euiFontWeightRegular}; -`; - const ReasonCell: React.FC<{ value: string | number | undefined | null; timelineId: string; @@ -82,8 +82,6 @@ const ReasonCell: React.FC<{ rowRenderers: RowRenderer[]; browserFields: BrowserFields; }> = ({ ecsData, rowRenderers, browserFields, timelineId, value }) => { - const [isOpen, setIsOpen] = useState(false); - const rowRenderer = useMemo(() => getRowRenderer(ecsData, rowRenderers), [ecsData, rowRenderers]); const rowRender = useMemo(() => { @@ -98,38 +96,17 @@ const ReasonCell: React.FC<{ ); }, [rowRenderer, browserFields, ecsData, timelineId]); - const handleTogglePopOver = useCallback(() => setIsOpen(!isOpen), [setIsOpen, isOpen]); - const handleClosePopOver = useCallback(() => setIsOpen(false), [setIsOpen]); - - const button = useMemo( - () => ( - <StyledEuiButtonEmpty - data-test-subj="reason-cell-button" - size="xs" - flush="left" - onClick={handleTogglePopOver} - > - {value} - </StyledEuiButtonEmpty> - ), - [value, handleTogglePopOver] - ); - return ( <> {rowRenderer && rowRender ? ( - <EuiPopover - isOpen={isOpen} - anchorPosition="rightCenter" - closePopover={handleClosePopOver} - panelClassName="withHoverActions__popover" - button={button} - > - <EuiPopoverTitle paddingSize="s"> - {i18n.EVENT_RENDERER_POPOVER_TITLE(eventRendererNames[rowRenderer.id] ?? '')} - </EuiPopoverTitle> - {rowRender} - </EuiPopover> + <> + {value} + <h4>{i18n.REASON_RENDERER_TITLE(eventRendererNames[rowRenderer.id] ?? '')}</h4> + <EuiSpacer size="xs" /> + <EuiPanel color="subdued" className="eui-xScroll" data-test-subj="reason-cell-renderer"> + <div className="eui-displayInlineBlock">{rowRender}</div> + </EuiPanel> + </> ) : ( value )} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts index a703c7afdaf7b..53cffa7d3708d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts @@ -52,8 +52,8 @@ export const EMPTY_STATUS = i18n.translate( } ); -export const EVENT_RENDERER_POPOVER_TITLE = (eventRendererName: string) => - i18n.translate('xpack.securitySolution.event.reason.eventRenderPopoverTitle', { +export const REASON_RENDERER_TITLE = (eventRendererName: string) => + i18n.translate('xpack.securitySolution.event.reason.reasonRendererTitle', { values: { eventRendererName }, defaultMessage: 'Event renderer: {eventRendererName} ', }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx index 5282276f8bb51..ef8fa01a63465 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx @@ -16,6 +16,8 @@ import { DroppableWrapper } from '../../../../common/components/drag_and_drop/dr import { mockBrowserFields } from '../../../../common/containers/source/mock'; import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../common/mock'; import { DefaultCellRenderer } from './default_cell_renderer'; +import { BrowserFields } from '../../../../../../timelines/common/search_strategy'; +import { Ecs } from '../../../../../common/ecs'; jest.mock('../../../../common/lib/kibana'); @@ -26,15 +28,16 @@ const mockImplementation = { }; describe('DefaultCellRenderer', () => { - const columnId = 'signal.rule.risk_score'; + const columnId = '@timestamp'; const eventId = '_id-123'; - const isDetails = true; const isExpandable = true; const isExpanded = true; const linkValues = ['foo', 'bar', '@baz']; const rowIndex = 3; const setCellProps = jest.fn(); const timelineId = 'test'; + const ecsData = {} as Ecs; + const browserFields = {} as BrowserFields; beforeEach(() => { jest.clearAllMocks(); @@ -44,14 +47,17 @@ describe('DefaultCellRenderer', () => { test('it invokes `getColumnRenderer` with the expected arguments', () => { const data = cloneDeep(mockTimelineData[0].data); const header = cloneDeep(defaultHeaders[0]); + const isDetails = true; mount( <TestProviders> <DragDropContextWrapper browserFields={mockBrowserFields}> <DroppableWrapper droppableId="testing"> <DefaultCellRenderer + browserFields={browserFields} columnId={columnId} data={data} + ecsData={ecsData} eventId={eventId} header={header} isDetails={isDetails} @@ -71,17 +77,21 @@ describe('DefaultCellRenderer', () => { expect(getColumnRenderer).toBeCalledWith(header.id, columnRenderers, data); }); - test('it invokes `renderColumn` with the expected arguments', () => { + test('if in tgrid expanded value, it invokes `renderColumn` with the expected arguments', () => { const data = cloneDeep(mockTimelineData[0].data); const header = cloneDeep(defaultHeaders[0]); + const isDetails = true; + const truncate = isDetails ? false : true; mount( <TestProviders> <DragDropContextWrapper browserFields={mockBrowserFields}> <DroppableWrapper droppableId="testing"> <DefaultCellRenderer + browserFields={browserFields} columnId={columnId} data={data} + ecsData={ecsData} eventId={eventId} header={header} isDetails={isDetails} @@ -92,6 +102,7 @@ describe('DefaultCellRenderer', () => { rowIndex={rowIndex} setCellProps={setCellProps} timelineId={timelineId} + truncate={truncate} /> </DroppableWrapper> </DragDropContextWrapper> @@ -99,14 +110,54 @@ describe('DefaultCellRenderer', () => { ); expect(mockImplementation.renderColumn).toBeCalledWith({ + asPlainText: false, + browserFields, columnName: header.id, + ecsData, eventId, field: header, + isDetails, isDraggable: true, linkValues, + rowRenderers: undefined, timelineId, - truncate: true, + truncate, values: ['2018-11-05T19:03:25.937Z'], }); }); + + test('if in tgrid expanded value, it renders ExpandedCellValueActions', () => { + const data = cloneDeep(mockTimelineData[0].data); + const header = cloneDeep(defaultHeaders[1]); + const isDetails = true; + const id = 'event.severity'; + const wrapper = mount( + <TestProviders> + <DragDropContextWrapper browserFields={mockBrowserFields}> + <DroppableWrapper droppableId="testing"> + <DefaultCellRenderer + browserFields={browserFields} + columnId={id} + ecsData={ecsData} + data={data} + eventId={eventId} + header={header} + isDetails={isDetails} + isDraggable={true} + isExpandable={isExpandable} + isExpanded={isExpanded} + linkValues={linkValues} + rowIndex={rowIndex} + setCellProps={setCellProps} + timelineId={timelineId} + /> + </DroppableWrapper> + </DragDropContextWrapper> + </TestProviders> + ); + + expect( + wrapper.find('[data-test-subj="data-grid-expanded-cell-value-actions"]').exists() + ).toBeTruthy(); + }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx index d45c8103d1cca..5b9fee621b417 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx @@ -12,36 +12,70 @@ import { columnRenderers } from '../body/renderers'; import { getColumnRenderer } from '../body/renderers/get_column_renderer'; import { CellValueElementProps } from '.'; +import { getLink } from '../../../../common/lib/cell_actions/helpers'; +import { + ExpandedCellValueActions, + StyledContent, +} from '../../../../common/lib/cell_actions/expanded_cell_value_actions'; + +const FIELDS_WITHOUT_CELL_ACTIONS = ['@timestamp', 'signal.rule.risk_score', 'signal.reason']; +const hasCellActions = (columnId?: string) => { + return columnId && FIELDS_WITHOUT_CELL_ACTIONS.indexOf(columnId) < 0; +}; export const DefaultCellRenderer: React.FC<CellValueElementProps> = ({ - columnId, + browserFields, data, + ecsData, eventId, + globalFilters, header, + isDetails, isDraggable, linkValues, + rowRenderers, setCellProps, timelineId, - rowRenderers, - browserFields, - ecsData, -}) => ( - <> - {getColumnRenderer(header.id, columnRenderers, data).renderColumn({ - columnName: header.id, - eventId, - field: header, - isDraggable, - linkValues, - timelineId, - truncate: true, - values: getMappedNonEcsValue({ - data, - fieldName: header.id, - }), - rowRenderers, - browserFields, - ecsData, - })} - </> -); + truncate, +}) => { + const values = getMappedNonEcsValue({ + data, + fieldName: header.id, + }); + const styledContentClassName = isDetails + ? 'eui-textBreakWord' + : 'eui-displayInlineBlock eui-textTruncate'; + return ( + <> + <StyledContent className={styledContentClassName} $isDetails={isDetails}> + {getColumnRenderer(header.id, columnRenderers, data).renderColumn({ + asPlainText: !!getLink(header.id, header.type), // we want to render value with links as plain text but keep other formatters like badge. + browserFields, + columnName: header.id, + ecsData, + eventId, + field: header, + isDetails, + isDraggable, + linkValues, + rowRenderers, + timelineId, + truncate, + values: getMappedNonEcsValue({ + data, + fieldName: header.id, + }), + })} + </StyledContent> + {isDetails && browserFields && hasCellActions(header.id) && ( + <ExpandedCellValueActions + browserFields={browserFields} + field={header.id} + globalFilters={globalFilters} + timelineId={timelineId} + value={values} + /> + )} + </> + ); +}; diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 1cec87fd35d1f..e595b905b998e 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -68,7 +68,7 @@ export interface StartPlugins { timelines: TimelinesUIStart; uiActions: UiActionsStart; ml?: MlPluginStart; - spaces: SpacesPluginStart; + spaces?: SpacesPluginStart; } export type StartServices = CoreStart & diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts index 71df9902223da..ee3bc5e1f21e3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts @@ -34,16 +34,18 @@ import { ISOLATE_HOST_ROUTE, UNISOLATE_HOST_ROUTE, metadataTransformPrefix, + ENDPOINT_ACTIONS_INDEX, } from '../../../../common/endpoint/constants'; import { EndpointAction, HostIsolationRequestBody, HostIsolationResponse, HostMetadata, + LogsEndpointAction, } from '../../../../common/endpoint/types'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { legacyMetadataSearchResponse } from '../metadata/support/test_support'; -import { ElasticsearchAssetType } from '../../../../../fleet/common'; +import { AGENT_ACTIONS_INDEX, ElasticsearchAssetType } from '../../../../../fleet/common'; import { CasesClientMock } from '../../../../../cases/server/client/mocks'; interface CallRouteInterface { @@ -109,7 +111,8 @@ describe('Host Isolation', () => { let callRoute: ( routePrefix: string, - opts: CallRouteInterface + opts: CallRouteInterface, + indexExists?: { endpointDsExists: boolean } ) => Promise<jest.Mocked<SecuritySolutionRequestHandlerContext>>; const superUser = { username: 'superuser', @@ -175,22 +178,42 @@ describe('Host Isolation', () => { // it returns the requestContext mock used in the call, to assert internal calls (e.g. the indexed document) callRoute = async ( routePrefix: string, - { body, idxResponse, searchResponse, mockUser, license }: CallRouteInterface + { body, idxResponse, searchResponse, mockUser, license }: CallRouteInterface, + indexExists?: { endpointDsExists: boolean } ): Promise<jest.Mocked<SecuritySolutionRequestHandlerContext>> => { const asUser = mockUser ? mockUser : superUser; (startContract.security.authc.getCurrentUser as jest.Mock).mockImplementationOnce( () => asUser ); + const ctx = createRouteHandlerContext(mockScopedClient, mockSavedObjectClient); - const withIdxResp = idxResponse ? idxResponse : { statusCode: 201 }; - ctx.core.elasticsearch.client.asCurrentUser.index = jest + // mock _index_template + ctx.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = jest .fn() - .mockImplementationOnce(() => Promise.resolve(withIdxResp)); - ctx.core.elasticsearch.client.asCurrentUser.search = jest + .mockImplementationOnce(() => { + if (indexExists) { + return Promise.resolve({ + body: true, + statusCode: 200, + }); + } + return Promise.resolve({ + body: false, + statusCode: 404, + }); + }); + const withIdxResp = idxResponse ? idxResponse : { statusCode: 201 }; + const mockIndexResponse = jest.fn().mockImplementation(() => Promise.resolve(withIdxResp)); + const mockSearchResponse = jest .fn() .mockImplementation(() => Promise.resolve({ body: legacyMetadataSearchResponse(searchResponse) }) ); + if (indexExists) { + ctx.core.elasticsearch.client.asInternalUser.index = mockIndexResponse; + } + ctx.core.elasticsearch.client.asCurrentUser.index = mockIndexResponse; + ctx.core.elasticsearch.client.asCurrentUser.search = mockSearchResponse; const withLicense = license ? license : Platinum; licenseEmitter.next(withLicense); const mockRequest = httpServerMock.createKibanaRequest({ body }); @@ -288,11 +311,6 @@ describe('Host Isolation', () => { ).mock.calls[0][0].body; expect(actionDoc.timeout).toEqual(300); }); - - it('succeeds when just an endpoint ID is provided', async () => { - await callRoute(ISOLATE_HOST_ROUTE, { body: { endpoint_ids: ['XYZ'] } }); - expect(mockResponse.ok).toBeCalled(); - }); it('sends the action to the correct agent when endpoint ID is given', async () => { const doc = docGen.generateHostMetadata(); const AgentID = doc.elastic.agent.id; @@ -326,6 +344,74 @@ describe('Host Isolation', () => { expect(actionDoc.data.command).toEqual('unisolate'); }); + describe('With endpoint data streams', () => { + it('handles unisolation', async () => { + const ctx = await callRoute( + UNISOLATE_HOST_ROUTE, + { + body: { endpoint_ids: ['XYZ'] }, + }, + { endpointDsExists: true } + ); + const actionDocs: [ + { index: string; body: LogsEndpointAction }, + { index: string; body: EndpointAction } + ] = [ + (ctx.core.elasticsearch.client.asCurrentUser.index as jest.Mock).mock.calls[0][0], + (ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock).mock.calls[1][0], + ]; + + expect(actionDocs[0].index).toEqual(ENDPOINT_ACTIONS_INDEX); + expect(actionDocs[1].index).toEqual(AGENT_ACTIONS_INDEX); + expect(actionDocs[0].body.EndpointActions.data.command).toEqual('unisolate'); + expect(actionDocs[1].body.data.command).toEqual('unisolate'); + }); + + it('handles isolation', async () => { + const ctx = await callRoute( + ISOLATE_HOST_ROUTE, + { + body: { endpoint_ids: ['XYZ'] }, + }, + { endpointDsExists: true } + ); + const actionDocs: [ + { index: string; body: LogsEndpointAction }, + { index: string; body: EndpointAction } + ] = [ + (ctx.core.elasticsearch.client.asCurrentUser.index as jest.Mock).mock.calls[0][0], + (ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock).mock.calls[1][0], + ]; + + expect(actionDocs[0].index).toEqual(ENDPOINT_ACTIONS_INDEX); + expect(actionDocs[1].index).toEqual(AGENT_ACTIONS_INDEX); + expect(actionDocs[0].body.EndpointActions.data.command).toEqual('isolate'); + expect(actionDocs[1].body.data.command).toEqual('isolate'); + }); + + it('handles errors', async () => { + const ErrMessage = 'Uh oh!'; + await callRoute( + UNISOLATE_HOST_ROUTE, + { + body: { endpoint_ids: ['XYZ'] }, + idxResponse: { + statusCode: 500, + body: { + result: ErrMessage, + }, + }, + }, + { endpointDsExists: true } + ); + + expect(mockResponse.ok).not.toBeCalled(); + const response = mockResponse.customError.mock.calls[0][0]; + expect(response.statusCode).toEqual(500); + expect((response.body as Error).message).toEqual(ErrMessage); + }); + }); + describe('License Level', () => { it('allows platinum license levels to isolate hosts', async () => { await callRoute(ISOLATE_HOST_ROUTE, { diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts index 45f0e851dfdd1..4652630649ffc 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts @@ -6,15 +6,25 @@ */ import moment from 'moment'; -import { RequestHandler } from 'src/core/server'; +import { RequestHandler, Logger } from 'src/core/server'; import uuid from 'uuid'; import { TypeOf } from '@kbn/config-schema'; import { CommentType } from '../../../../../cases/common'; import { CasesByAlertId } from '../../../../../cases/common/api/cases/case'; import { HostIsolationRequestSchema } from '../../../../common/endpoint/schema/actions'; -import { ISOLATE_HOST_ROUTE, UNISOLATE_HOST_ROUTE } from '../../../../common/endpoint/constants'; +import { + ENDPOINT_ACTIONS_DS, + ENDPOINT_ACTION_RESPONSES_DS, + ISOLATE_HOST_ROUTE, + UNISOLATE_HOST_ROUTE, +} from '../../../../common/endpoint/constants'; import { AGENT_ACTIONS_INDEX } from '../../../../../fleet/common'; -import { EndpointAction, HostMetadata } from '../../../../common/endpoint/types'; +import { + EndpointAction, + HostMetadata, + LogsEndpointAction, + LogsEndpointActionResponse, +} from '../../../../common/endpoint/types'; import { SecuritySolutionPluginRouter, SecuritySolutionRequestHandlerContext, @@ -52,6 +62,57 @@ export function registerHostIsolationRoutes( ); } +const createFailedActionResponseEntry = async ({ + context, + doc, + logger, +}: { + context: SecuritySolutionRequestHandlerContext; + doc: LogsEndpointActionResponse; + logger: Logger; +}): Promise<void> => { + const esClient = context.core.elasticsearch.client.asCurrentUser; + try { + await esClient.index<LogsEndpointActionResponse>({ + index: `${ENDPOINT_ACTION_RESPONSES_DS}-default`, + body: { + ...doc, + error: { + code: '424', + message: 'Failed to deliver action request to fleet', + }, + }, + }); + } catch (e) { + logger.error(e); + } +}; + +const doLogsEndpointActionDsExists = async ({ + context, + logger, + dataStreamName, +}: { + context: SecuritySolutionRequestHandlerContext; + logger: Logger; + dataStreamName: string; +}): Promise<boolean> => { + try { + const esClient = context.core.elasticsearch.client.asInternalUser; + const doesIndexTemplateExist = await esClient.indices.existsIndexTemplate({ + name: dataStreamName, + }); + return doesIndexTemplateExist.statusCode === 404 ? false : true; + } catch (error) { + const errorType = error?.type ?? ''; + if (errorType !== 'resource_not_found_exception') { + logger.error(error); + throw error; + } + return false; + } +}; + export const isolationRequestHandler = function ( endpointContext: EndpointAppContext, isolate: boolean @@ -106,43 +167,121 @@ export const isolationRequestHandler = function ( caseIDs = [...new Set(caseIDs)]; // create an Action ID and dispatch it to ES & Fleet Server - const esClient = context.core.elasticsearch.client.asCurrentUser; const actionID = uuid.v4(); - let result; + + let fleetActionIndexResult; + let logsEndpointActionsResult; + + const agents = endpointData.map((endpoint: HostMetadata) => endpoint.elastic.agent.id); + const doc = { + '@timestamp': moment().toISOString(), + agent: { + id: agents, + }, + EndpointActions: { + action_id: actionID, + expiration: moment().add(2, 'weeks').toISOString(), + type: 'INPUT_ACTION', + input_type: 'endpoint', + data: { + command: isolate ? 'isolate' : 'unisolate', + comment: req.body.comment ?? undefined, + }, + } as Omit<EndpointAction, 'agents' | 'user_id'>, + user: { + id: user!.username, + }, + }; + + // if .logs-endpoint.actions data stream exists + // try to create action request record in .logs-endpoint.actions DS as the current user + // (from >= v7.16, use this check to ensure the current user has privileges to write to the new index) + // and allow only users with superuser privileges to write to fleet indices + const logger = endpointContext.logFactory.get('host-isolation'); + const doesLogsEndpointActionsDsExist = await doLogsEndpointActionDsExists({ + context, + logger, + dataStreamName: ENDPOINT_ACTIONS_DS, + }); + // if the new endpoint indices/data streams exists + // write the action request to the new index as the current user + if (doesLogsEndpointActionsDsExist) { + try { + const esClient = context.core.elasticsearch.client.asCurrentUser; + logsEndpointActionsResult = await esClient.index<LogsEndpointAction>({ + index: `${ENDPOINT_ACTIONS_DS}-default`, + body: { + ...doc, + }, + }); + if (logsEndpointActionsResult.statusCode !== 201) { + return res.customError({ + statusCode: 500, + body: { + message: logsEndpointActionsResult.body.result, + }, + }); + } + } catch (e) { + return res.customError({ + statusCode: 500, + body: { message: e }, + }); + } + } + try { - result = await esClient.index<EndpointAction>({ + let esClient = context.core.elasticsearch.client.asCurrentUser; + if (doesLogsEndpointActionsDsExist) { + // create action request record as system user with user in .fleet-actions + esClient = context.core.elasticsearch.client.asInternalUser; + } + // write as the current user if the new indices do not exist + // <v7.16 requires the current user to be super user + fleetActionIndexResult = await esClient.index<EndpointAction>({ index: AGENT_ACTIONS_INDEX, body: { - action_id: actionID, - '@timestamp': moment().toISOString(), - expiration: moment().add(2, 'weeks').toISOString(), - type: 'INPUT_ACTION', - input_type: 'endpoint', - agents: endpointData.map((endpt: HostMetadata) => endpt.elastic.agent.id), - user_id: user!.username, + ...doc.EndpointActions, + '@timestamp': doc['@timestamp'], + agents, timeout: 300, // 5 minutes - data: { - command: isolate ? 'isolate' : 'unisolate', - comment: req.body.comment ?? undefined, - }, + user_id: doc.user.id, }, }); + + if (fleetActionIndexResult.statusCode !== 201) { + return res.customError({ + statusCode: 500, + body: { + message: fleetActionIndexResult.body.result, + }, + }); + } } catch (e) { + // create entry in .logs-endpoint.action.responses-default data stream + // when writing to .fleet-actions fails + if (doesLogsEndpointActionsDsExist) { + await createFailedActionResponseEntry({ + context, + doc: { + '@timestamp': moment().toISOString(), + agent: doc.agent, + EndpointActions: { + action_id: doc.EndpointActions.action_id, + completed_at: moment().toISOString(), + started_at: moment().toISOString(), + data: doc.EndpointActions.data, + }, + }, + logger, + }); + } return res.customError({ statusCode: 500, body: { message: e }, }); } - if (result.statusCode !== 201) { - return res.customError({ - statusCode: 500, - body: { - message: result.body.result, - }, - }); - } - // Update all cases with a comment if (caseIDs.length > 0) { const targets = endpointData.map((endpt: HostMetadata) => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index c3c3ac47baf9a..200246ba1a367 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -34,7 +34,7 @@ import { getFinalizeSignalsMigrationSchemaMock } from '../../../../../common/det import { EqlSearchResponse } from '../../../../../common/detection_engine/types'; import { getSignalsMigrationStatusSchemaMock } from '../../../../../common/detection_engine/schemas/request/get_signals_migration_status_schema.mock'; import { RuleParams } from '../../schemas/rule_schemas'; -import { Alert } from '../../../../../../alerting/common'; +import { SanitizedAlert, ResolvedSanitizedRule } from '../../../../../../alerting/common'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; import { getPerformBulkActionSchemaMock } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock'; import { RuleExecutionStatus } from '../../../../../common/detection_engine/schemas/common/schemas'; @@ -87,6 +87,13 @@ export const getReadRequest = () => query: { rule_id: 'rule-1' }, }); +export const getReadRequestWithId = (id: string) => + requestMock.create({ + method: 'get', + path: DETECTION_ENGINE_RULES_URL, + query: { id }, + }); + export const getFindRequest = () => requestMock.create({ method: 'get', @@ -362,7 +369,7 @@ export const nonRuleAlert = (isRuleRegistryEnabled: boolean) => ({ export const getAlertMock = <T extends RuleParams>( isRuleRegistryEnabled: boolean, params: T -): Alert<T> => ({ +): SanitizedAlert<T> => ({ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', name: 'Detect Root/Admin Users', tags: [`${INTERNAL_RULE_ID_KEY}:rule-1`, `${INTERNAL_IMMUTABLE_KEY}:false`], @@ -378,7 +385,6 @@ export const getAlertMock = <T extends RuleParams>( notifyWhen: null, createdBy: 'elastic', updatedBy: 'elastic', - apiKey: null, apiKeyOwner: 'elastic', muteAll: false, mutedInstanceIds: [], @@ -389,6 +395,14 @@ export const getAlertMock = <T extends RuleParams>( }, }); +export const resolveAlertMock = <T extends RuleParams>( + isRuleRegistryEnabled: boolean, + params: T +): ResolvedSanitizedRule<T> => ({ + outcome: 'exactMatch', + ...getAlertMock(isRuleRegistryEnabled, params), +}); + export const updateActionResult = (): ActionResult => ({ id: 'result-1', actionTypeId: 'action-id-1', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts index 35b3ef3d9cf85..7c447660acb45 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts @@ -8,7 +8,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { getEmptyFindResult, - getAlertMock, + resolveAlertMock, getDeleteRequest, getFindResultWithSingleHit, getDeleteRequestById, @@ -45,8 +45,8 @@ describe.each([ }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by id', async () => { - clients.rulesClient.get.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + clients.rulesClient.resolve.mockResolvedValue( + resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) ); const response = await server.inject(getDeleteRequestById(), context); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts index d6c18088800ba..37b8228ac1e9b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts @@ -12,11 +12,14 @@ import { readRulesRoute } from './read_rules_route'; import { getEmptyFindResult, getReadRequest, + getReadRequestWithId, getFindResultWithSingleHit, nonRuleFindResult, getEmptySavedObjectsResponse, + resolveAlertMock, } from '../__mocks__/request_responses'; import { requestMock, requestContextMock, serverMock } from '../__mocks__'; +import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; describe.each([ ['Legacy', false], @@ -26,6 +29,7 @@ describe.each([ let { clients, context } = requestContextMock.createTools(); let logger: ReturnType<typeof loggingSystemMock.createLogger>; + const myFakeId = '99403909-ca9b-49ba-9d7a-7e5320e68d05'; beforeEach(() => { server = serverMock.create(); logger = loggingSystemMock.createLogger(); @@ -35,6 +39,12 @@ describe.each([ clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); // successful transform clients.ruleExecutionLogClient.find.mockResolvedValue([]); + clients.rulesClient.resolve.mockResolvedValue({ + ...resolveAlertMock(isRuleRegistryEnabled, { + ...getQueryRuleParams(), + }), + id: myFakeId, + }); readRulesRoute(server.router, logger, isRuleRegistryEnabled); }); @@ -44,6 +54,37 @@ describe.each([ expect(response.status).toEqual(200); }); + test('returns 200 when reading a single rule outcome === exactMatch', async () => { + const response = await server.inject(getReadRequestWithId(myFakeId), context); + expect(response.status).toEqual(200); + }); + + test('returns 200 when reading a single rule outcome === aliasMatch', async () => { + clients.rulesClient.resolve.mockResolvedValue({ + ...resolveAlertMock(isRuleRegistryEnabled, { + ...getQueryRuleParams(), + }), + id: myFakeId, + outcome: 'aliasMatch', + }); + const response = await server.inject(getReadRequestWithId(myFakeId), context); + expect(response.status).toEqual(200); + }); + + test('returns 200 when reading a single rule outcome === conflict', async () => { + clients.rulesClient.resolve.mockResolvedValue({ + ...resolveAlertMock(isRuleRegistryEnabled, { + ...getQueryRuleParams(), + }), + id: myFakeId, + outcome: 'conflict', + alias_target_id: 'myaliastargetid', + }); + const response = await server.inject(getReadRequestWithId(myFakeId), context); + expect(response.status).toEqual(200); + expect(response.body.alias_target_id).toEqual('myaliastargetid'); + }); + test('returns 404 if alertClient is not available on the route', async () => { context.alerting!.getRulesClient = jest.fn(); const response = await server.inject(getReadRequest(), context); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/event_log_adapter/event_log_adapter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/event_log_adapter/event_log_adapter.ts index 6b1a0cd5b18d0..086cc12788a40 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/event_log_adapter/event_log_adapter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/event_log_adapter/event_log_adapter.ts @@ -5,7 +5,10 @@ * 2.0. */ +import { sum } from 'lodash'; +import { SavedObjectsClientContract } from '../../../../../../../../src/core/server'; import { IEventLogService } from '../../../../../../event_log/server'; +import { SavedObjectsAdapter } from '../saved_objects_adapter/saved_objects_adapter'; import { FindBulkExecutionLogArgs, FindExecutionLogArgs, @@ -18,21 +21,32 @@ import { EventLogClient } from './event_log_client'; export class EventLogAdapter implements IRuleExecutionLogClient { private eventLogClient: EventLogClient; + /** + * @deprecated Saved objects adapter is used during the transition period while the event log doesn't support all features needed to implement the execution log. + * We use savedObjectsAdapter to write/read the latest rule execution status and eventLogClient to read/write historical execution data. + * We can remove savedObjectsAdapter as soon as the event log supports all methods that we need (find, findBulk). + */ + private savedObjectsAdapter: IRuleExecutionLogClient; - constructor(eventLogService: IEventLogService) { + constructor(eventLogService: IEventLogService, savedObjectsClient: SavedObjectsClientContract) { this.eventLogClient = new EventLogClient(eventLogService); + this.savedObjectsAdapter = new SavedObjectsAdapter(savedObjectsClient); } - public async find({ ruleId, logsCount = 1, spaceId }: FindExecutionLogArgs) { - return []; // TODO Implement + public async find(args: FindExecutionLogArgs) { + return this.savedObjectsAdapter.find(args); } - public async findBulk({ ruleIds, logsCount = 1, spaceId }: FindBulkExecutionLogArgs) { - return {}; // TODO Implement + public async findBulk(args: FindBulkExecutionLogArgs) { + return this.savedObjectsAdapter.findBulk(args); } - public async update({ attributes, spaceId, ruleName, ruleType }: UpdateExecutionLogArgs) { - // execution events are immutable, so we just log a status change istead of updating previous + public async update(args: UpdateExecutionLogArgs) { + const { attributes, spaceId, ruleName, ruleType } = args; + + await this.savedObjectsAdapter.update(args); + + // EventLog execution events are immutable, so we just log a status change istead of updating previous if (attributes.status) { this.eventLogClient.logStatusChange({ ruleName, @@ -45,16 +59,15 @@ export class EventLogAdapter implements IRuleExecutionLogClient { } public async delete(id: string) { - // execution events are immutable, nothing to do here + await this.savedObjectsAdapter.delete(id); + + // EventLog execution events are immutable, nothing to do here } - public async logExecutionMetrics({ - ruleId, - spaceId, - ruleType, - ruleName, - metrics, - }: LogExecutionMetricsArgs) { + public async logExecutionMetrics(args: LogExecutionMetricsArgs) { + const { ruleId, spaceId, ruleType, ruleName, metrics } = args; + await this.savedObjectsAdapter.logExecutionMetrics(args); + this.eventLogClient.logExecutionMetrics({ ruleId, ruleName, @@ -62,16 +75,19 @@ export class EventLogAdapter implements IRuleExecutionLogClient { spaceId, metrics: { executionGapDuration: metrics.executionGap?.asSeconds(), - totalIndexingDuration: metrics.indexingDurations?.reduce( - (acc, cur) => acc + Number(cur), - 0 - ), - totalSearchDuration: metrics.searchDurations?.reduce((acc, cur) => acc + Number(cur), 0), + totalIndexingDuration: metrics.indexingDurations + ? sum(metrics.indexingDurations.map(Number)) + : undefined, + totalSearchDuration: metrics.searchDurations + ? sum(metrics.searchDurations.map(Number)) + : undefined, }, }); } public async logStatusChange(args: LogStatusChangeArgs) { + await this.savedObjectsAdapter.logStatusChange(args); + if (args.metrics) { this.logExecutionMetrics({ ruleId: args.ruleId, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/index.ts new file mode 100644 index 0000000000000..5c7d9a875056a --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './rule_execution_log_client'; +export * from './types'; +export * from './utils/normalization'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_execution_log_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_execution_log_client.ts index 87a3b00cf4ed3..7ae2f179f9692 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_execution_log_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_execution_log_client.ts @@ -18,6 +18,7 @@ import { UpdateExecutionLogArgs, UnderlyingLogClient, } from './types'; +import { truncateMessage } from './utils/normalization'; export interface RuleExecutionLogClientArgs { savedObjectsClient: SavedObjectsClientContract; @@ -38,7 +39,7 @@ export class RuleExecutionLogClient implements IRuleExecutionLogClient { this.client = new SavedObjectsAdapter(savedObjectsClient); break; case UnderlyingLogClient.eventLog: - this.client = new EventLogAdapter(eventLogService); + this.client = new EventLogAdapter(eventLogService, savedObjectsClient); break; } } @@ -52,7 +53,16 @@ export class RuleExecutionLogClient implements IRuleExecutionLogClient { } public async update(args: UpdateExecutionLogArgs) { - return this.client.update(args); + const { lastFailureMessage, lastSuccessMessage, ...restAttributes } = args.attributes; + + return this.client.update({ + ...args, + attributes: { + lastFailureMessage: truncateMessage(lastFailureMessage), + lastSuccessMessage: truncateMessage(lastSuccessMessage), + ...restAttributes, + }, + }); } public async delete(id: string) { @@ -64,6 +74,10 @@ export class RuleExecutionLogClient implements IRuleExecutionLogClient { } public async logStatusChange(args: LogStatusChangeArgs) { - return this.client.logStatusChange(args); + const message = args.message ? truncateMessage(args.message) : args.message; + return this.client.logStatusChange({ + ...args, + message, + }); } } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/utils/normalization.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/utils/normalization.ts new file mode 100644 index 0000000000000..baaee9446eee3 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/utils/normalization.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 { take, toString, truncate, uniq } from 'lodash'; + +// When we write rule execution status updates to `siem-detection-engine-rule-status` saved objects +// or to event log, we write success and failure messages as well. Those messages are built from +// N errors collected during the "big loop" in the Detection Engine, where N can be very large. +// When N is large the resulting message strings are so large that these documents are up to 26MB. +// These large documents may cause migrations to fail because a batch of 1000 documents easily +// exceed Elasticsearch's `http.max_content_length` which defaults to 100mb. +// In order to fix that, we need to truncate those messages to an adequate MAX length. +// https://github.com/elastic/kibana/pull/112257 + +const MAX_MESSAGE_LENGTH = 10240; +const MAX_LIST_LENGTH = 20; + +export const truncateMessage = (value: unknown): string | undefined => { + if (value === undefined) { + return value; + } + + const str = toString(value); + return truncate(str, { length: MAX_MESSAGE_LENGTH }); +}; + +export const truncateMessageList = (list: string[]): string[] => { + const deduplicatedList = uniq(list); + return take(deduplicatedList, MAX_LIST_LENGTH); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts similarity index 90% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_factory.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts index 9ea36abe997c3..77981d92b2ba7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts @@ -14,7 +14,7 @@ import { parseScheduleDates } from '@kbn/securitysolution-io-ts-utils'; import { ListArray } from '@kbn/securitysolution-io-ts-list-types'; import { toError } from '@kbn/securitysolution-list-api'; -import { createPersistenceRuleTypeFactory } from '../../../../../rule_registry/server'; +import { createPersistenceRuleTypeWrapper } from '../../../../../rule_registry/server'; import { buildRuleMessageFactory } from './factories/build_rule_message_factory'; import { checkPrivilegesFromEsClient, @@ -22,10 +22,14 @@ import { getRuleRangeTuples, hasReadIndexPrivileges, hasTimestampFields, - isMachineLearningParams, + isEqlParams, + isQueryParams, + isSavedQueryParams, + isThreatParams, + isThresholdParams, } from '../signals/utils'; import { DEFAULT_MAX_SIGNALS, DEFAULT_SEARCH_AFTER_PAGE_SIZE } from '../../../../common/constants'; -import { CreateSecurityRuleTypeFactory } from './types'; +import { CreateSecurityRuleTypeWrapper } from './types'; import { getListClient } from './utils/get_list_client'; import { NotificationRuleTypeParams, @@ -34,16 +38,17 @@ import { import { getNotificationResultsLink } from '../notifications/utils'; import { createResultObject } from './utils'; import { bulkCreateFactory, wrapHitsFactory, wrapSequencesFactory } from './factories'; -import { RuleExecutionLogClient } from '../rule_execution_log/rule_execution_log_client'; +import { RuleExecutionLogClient, truncateMessageList } from '../rule_execution_log'; import { RuleExecutionStatus } from '../../../../common/detection_engine/schemas/common/schemas'; import { scheduleThrottledNotificationActions } from '../notifications/schedule_throttle_notification_actions'; +import { AlertAttributes } from '../signals/types'; /* eslint-disable complexity */ -export const createSecurityRuleTypeFactory: CreateSecurityRuleTypeFactory = +export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = ({ lists, logger, config, ruleDataClient, eventLogService }) => (type) => { const { alertIgnoreFields: ignoreFields, alertMergeStrategy: mergeStrategy } = config; - const persistenceRuleType = createPersistenceRuleTypeFactory({ ruleDataClient, logger }); + const persistenceRuleType = createPersistenceRuleTypeWrapper({ ruleDataClient, logger }); return persistenceRuleType({ ...type, async executor(options) { @@ -69,7 +74,10 @@ export const createSecurityRuleTypeFactory: CreateSecurityRuleTypeFactory = eventLogService, underlyingClient: config.ruleExecutionLog.underlyingClient, }); - const ruleSO = await savedObjectsClient.get('alert', alertId); + const ruleSO = await savedObjectsClient.get<AlertAttributes<typeof params>>( + 'alert', + alertId + ); const { actions, @@ -107,7 +115,16 @@ export const createSecurityRuleTypeFactory: CreateSecurityRuleTypeFactory = // move this collection of lines into a function in utils // so that we can use it in create rules route, bulk, etc. try { - if (!isMachineLearningParams(params)) { + // Typescript 4.1.3 can't figure out that `!isMachineLearningParams(params)` also excludes the only rule type + // of rule params that doesn't include `params.index`, but Typescript 4.3.5 does compute the stricter type correctly. + // When we update Typescript to >= 4.3.5, we can replace this logic with `!isMachineLearningParams(params)` again. + if ( + isEqlParams(params) || + isThresholdParams(params) || + isQueryParams(params) || + isSavedQueryParams(params) || + isThreatParams(params) + ) { const index = params.index; const hasTimestampOverride = !!timestampOverride; @@ -254,7 +271,7 @@ export const createSecurityRuleTypeFactory: CreateSecurityRuleTypeFactory = createdSignals, createdSignalsCount: createdSignals.length, errors: result.errors.concat(runResult.errors), - lastLookbackDate: runResult.lastLookbackDate, + lastLookbackDate: runResult.lastLookBackDate, searchAfterTimes: result.searchAfterTimes.concat(runResult.searchAfterTimes), state: runState, success: result.success && runResult.success, @@ -265,7 +282,9 @@ export const createSecurityRuleTypeFactory: CreateSecurityRuleTypeFactory = } if (result.warningMessages.length) { - const warningMessage = buildRuleMessage(result.warningMessages.join()); + const warningMessage = buildRuleMessage( + truncateMessageList(result.warningMessages).join() + ); await ruleStatusClient.logStatusChange({ ...basicLogArguments, newStatus: RuleExecutionStatus['partial failure'], @@ -355,7 +374,7 @@ export const createSecurityRuleTypeFactory: CreateSecurityRuleTypeFactory = } else { const errorMessage = buildRuleMessage( 'Bulk Indexing of signals failed:', - result.errors.join() + truncateMessageList(result.errors).join() ); logger.error(errorMessage); await ruleStatusClient.logStatusChange({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.test.ts index 43860d396ac5d..486a692ba29f4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.test.ts @@ -12,6 +12,7 @@ import { allowedExperimentalValues } from '../../../../../common/experimental_fe import { createEqlAlertType } from './create_eql_alert_type'; import { createRuleTypeMocks } from '../__mocks__/rule_type'; import { getEqlRuleParams } from '../../schemas/rule_schemas.mock'; +import { createSecurityRuleTypeWrapper } from '../create_security_rule_type_wrapper'; import { createMockConfig } from '../../routes/__mocks__'; jest.mock('../../rule_execution_log/rule_execution_log_client'); @@ -23,15 +24,20 @@ describe('Event correlation alerts', () => { query: 'any where false', }; const { services, dependencies, executor } = createRuleTypeMocks('eql', params); - const eqlAlertType = createEqlAlertType({ - experimentalFeatures: allowedExperimentalValues, + const securityRuleTypeWrapper = createSecurityRuleTypeWrapper({ lists: dependencies.lists, logger: dependencies.logger, config: createMockConfig(), ruleDataClient: dependencies.ruleDataClient, eventLogService: dependencies.eventLogService, - version: '1.0.0', }); + const eqlAlertType = securityRuleTypeWrapper( + createEqlAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(eqlAlertType); services.scopedClusterClient.asCurrentUser.search.mockReturnValue( elasticsearchClientMock.createSuccessTransportRequestPromise({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts index 9324b469bf644..f09f013301dea 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts @@ -6,24 +6,16 @@ */ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; -import { PersistenceServices } from '../../../../../../rule_registry/server'; import { EQL_RULE_TYPE_ID } from '../../../../../common/constants'; -import { eqlRuleParams, EqlRuleParams } from '../../schemas/rule_schemas'; +import { EqlRuleParams, eqlRuleParams } from '../../schemas/rule_schemas'; import { eqlExecutor } from '../../signals/executors/eql'; -import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; -import { CreateRuleOptions } from '../types'; +import { CreateRuleOptions, SecurityAlertType } from '../types'; -export const createEqlAlertType = (createOptions: CreateRuleOptions) => { - const { experimentalFeatures, lists, logger, config, ruleDataClient, version, eventLogService } = - createOptions; - const createSecurityRuleType = createSecurityRuleTypeFactory({ - lists, - logger, - config, - ruleDataClient, - eventLogService, - }); - return createSecurityRuleType<EqlRuleParams, {}, PersistenceServices, {}>({ +export const createEqlAlertType = ( + createOptions: CreateRuleOptions +): SecurityAlertType<EqlRuleParams, {}, {}, 'default'> => { + const { experimentalFeatures, logger, version } = createOptions; + return { id: EQL_RULE_TYPE_ID, name: 'Event Correlation Rule', validate: { @@ -83,5 +75,5 @@ export const createEqlAlertType = (createOptions: CreateRuleOptions) => { }); return { ...result, state }; }, - }); + }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts index af0a8a27f2b25..3c12adbca3e44 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts @@ -16,7 +16,6 @@ import { BuildRuleMessage } from '../../signals/rule_messages'; import { errorAggregator, makeFloatString } from '../../signals/utils'; import { RefreshTypes } from '../../types'; import { PersistenceAlertService } from '../../../../../../rule_registry/server'; -import { AlertInstanceContext } from '../../../../../../alerting/common'; export interface GenericBulkCreateResponse<T> { success: boolean; @@ -27,9 +26,9 @@ export interface GenericBulkCreateResponse<T> { } export const bulkCreateFactory = - <TContext extends AlertInstanceContext>( + ( logger: Logger, - alertWithPersistence: PersistenceAlertService<TContext>, + alertWithPersistence: PersistenceAlertService, buildRuleMessage: BuildRuleMessage, refreshForBulkCreate: RefreshTypes ) => @@ -61,6 +60,19 @@ export const bulkCreateFactory = `individual bulk process time took: ${makeFloatString(end - start)} milliseconds` ) ); + + if (response == null) { + return { + errors: [ + 'alertWithPersistence returned undefined response. Alerts as Data write flag may be disabled.', + ], + success: false, + bulkCreateDuration: makeFloatString(end - start), + createdItemsCount: 0, + createdItems: [], + }; + } + logger.debug( buildRuleMessage(`took property says bulk took: ${response.body.took} milliseconds`) ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts index 3db4f5686abdc..576e409378213 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts @@ -16,6 +16,7 @@ import { createIndicatorMatchAlertType } from './create_indicator_match_alert_ty import { sampleDocNoSortId } from '../../signals/__mocks__/es_results'; import { CountResponse } from 'kibana/server'; import { RuleParams } from '../../schemas/rule_schemas'; +import { createSecurityRuleTypeWrapper } from '../create_security_rule_type_wrapper'; import { createMockConfig } from '../../routes/__mocks__'; jest.mock('../utils/get_list_client', () => ({ @@ -50,18 +51,23 @@ describe('Indicator Match Alerts', () => { to: 'now', type: 'threat_match', }; + const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); + const securityRuleTypeWrapper = createSecurityRuleTypeWrapper({ + lists: dependencies.lists, + logger: dependencies.logger, + config: createMockConfig(), + ruleDataClient: dependencies.ruleDataClient, + eventLogService: dependencies.eventLogService, + }); it('does not send an alert when no events found', async () => { - const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); - const indicatorMatchAlertType = createIndicatorMatchAlertType({ - experimentalFeatures: allowedExperimentalValues, - lists: dependencies.lists, - logger: dependencies.logger, - config: createMockConfig(), - ruleDataClient: dependencies.ruleDataClient, - eventLogService: dependencies.eventLogService, - version: '1.0.0', - }); + const indicatorMatchAlertType = securityRuleTypeWrapper( + createIndicatorMatchAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(indicatorMatchAlertType); @@ -92,16 +98,13 @@ describe('Indicator Match Alerts', () => { }); it('does not send an alert when no enrichments are found', async () => { - const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); - const indicatorMatchAlertType = createIndicatorMatchAlertType({ - experimentalFeatures: allowedExperimentalValues, - lists: dependencies.lists, - logger: dependencies.logger, - config: createMockConfig(), - ruleDataClient: dependencies.ruleDataClient, - eventLogService: dependencies.eventLogService, - version: '1.0.0', - }); + const indicatorMatchAlertType = securityRuleTypeWrapper( + createIndicatorMatchAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(indicatorMatchAlertType); @@ -130,16 +133,13 @@ describe('Indicator Match Alerts', () => { }); it('sends an alert when enrichments are found', async () => { - const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); - const indicatorMatchAlertType = createIndicatorMatchAlertType({ - experimentalFeatures: allowedExperimentalValues, - lists: dependencies.lists, - logger: dependencies.logger, - config: createMockConfig(), - ruleDataClient: dependencies.ruleDataClient, - eventLogService: dependencies.eventLogService, - version: '1.0.0', - }); + const indicatorMatchAlertType = securityRuleTypeWrapper( + createIndicatorMatchAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(indicatorMatchAlertType); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts index c30fdd7d99c2a..ee0688840811a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts @@ -6,24 +6,16 @@ */ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; -import { PersistenceServices } from '../../../../../../rule_registry/server'; import { INDICATOR_RULE_TYPE_ID } from '../../../../../common/constants'; -import { threatRuleParams, ThreatRuleParams } from '../../schemas/rule_schemas'; +import { ThreatRuleParams, threatRuleParams } from '../../schemas/rule_schemas'; import { threatMatchExecutor } from '../../signals/executors/threat_match'; -import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; -import { CreateRuleOptions } from '../types'; +import { CreateRuleOptions, SecurityAlertType } from '../types'; -export const createIndicatorMatchAlertType = (createOptions: CreateRuleOptions) => { - const { experimentalFeatures, lists, logger, config, ruleDataClient, version, eventLogService } = - createOptions; - const createSecurityRuleType = createSecurityRuleTypeFactory({ - lists, - logger, - config, - ruleDataClient, - eventLogService, - }); - return createSecurityRuleType<ThreatRuleParams, {}, PersistenceServices, {}>({ +export const createIndicatorMatchAlertType = ( + createOptions: CreateRuleOptions +): SecurityAlertType<ThreatRuleParams, {}, {}, 'default'> => { + const { experimentalFeatures, logger, version } = createOptions; + return { id: INDICATOR_RULE_TYPE_ID, name: 'Indicator Match Rule', validate: { @@ -86,5 +78,5 @@ export const createIndicatorMatchAlertType = (createOptions: CreateRuleOptions) }); return { ...result, state }; }, - }); + }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml.ts deleted file mode 100644 index e0ad333b76a24..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -/* - -import { schema } from '@kbn/config-schema'; -import { KibanaRequest, Logger } from 'src/core/server'; -import { SavedObject } from 'src/core/types'; - -import { buildEsQuery, IIndexPattern } from '../../../../../../../src/plugins/data/common'; - -import { createPersistenceRuleTypeFactory } from '../../../../../rule_registry/server'; -import { ML_RULE_TYPE_ID } from '../../../../common/constants'; -import { SecurityRuleRegistry } from '../../../plugin'; - -const createSecurityMlRuleType = createPersistenceRuleTypeFactory<SecurityRuleRegistry>(); - -import { - AlertInstanceContext, - AlertInstanceState, - AlertServices, -} from '../../../../../alerting/server'; -import { ListClient } from '../../../../../lists/server'; -import { isJobStarted } from '../../../../common/machine_learning/helpers'; -import { ExceptionListItemSchema } from '../../../../common/shared_imports'; -import { SetupPlugins } from '../../../plugin'; -import { RefreshTypes } from '../types'; -import { bulkCreateMlSignals } from '../signals/bulk_create_ml_signals'; -import { filterEventsAgainstList } from '../signals/filters/filter_events_against_list'; -import { findMlSignals } from '../signals/find_ml_signals'; -import { BuildRuleMessage } from '../signals/rule_messages'; -import { RuleStatusService } from '../signals/rule_status_service'; -import { MachineLearningRuleAttributes } from '../signals/types'; -import { createErrorsFromShard, createSearchAfterReturnType, mergeReturns } from '../signals/utils'; - -export const mlAlertType = createSecurityMlRuleType({ - id: ML_RULE_TYPE_ID, - name: 'Machine Learning Rule', - validate: { - params: schema.object({ - indexPatterns: schema.arrayOf(schema.string()), - customQuery: schema.string(), - }), - }, - actionGroups: [ - { - id: 'default', - name: 'Default', - }, - ], - defaultActionGroupId: 'default', - actionVariables: { - context: [{ name: 'server', description: 'the server' }], - }, - minimumLicenseRequired: 'basic', - isExportable: false, - producer: 'security-solution', - async executor({ - services: { alertWithPersistence, findAlerts }, - params: { indexPatterns, customQuery }, - }) { - return { - lastChecked: new Date(), - }; - }, -}); -*/ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.test.ts index bffc20c3df1e3..b7a099b10e275 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.test.ts @@ -14,6 +14,7 @@ import { createRuleTypeMocks } from '../__mocks__/rule_type'; import { createMlAlertType } from './create_ml_alert_type'; import { RuleParams } from '../../schemas/rule_schemas'; +import { createSecurityRuleTypeWrapper } from '../create_security_rule_type_wrapper'; import { createMockConfig } from '../../routes/__mocks__'; jest.mock('../../signals/bulk_create_ml_signals'); @@ -94,16 +95,21 @@ describe('Machine Learning Alerts', () => { }, ]); const { dependencies, executor } = createRuleTypeMocks('machine_learning', params); - const mlAlertType = createMlAlertType({ - experimentalFeatures: allowedExperimentalValues, + const securityRuleTypeWrapper = createSecurityRuleTypeWrapper({ lists: dependencies.lists, logger: dependencies.logger, config: createMockConfig(), - ml: mlMock, ruleDataClient: dependencies.ruleDataClient, eventLogService: dependencies.eventLogService, - version: '1.0.0', }); + const mlAlertType = securityRuleTypeWrapper( + createMlAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + ml: mlMock, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(mlAlertType); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts index ac2d3f14831a4..756757c7c9956 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts @@ -6,23 +6,16 @@ */ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; -import { PersistenceServices } from '../../../../../../rule_registry/server'; import { ML_RULE_TYPE_ID } from '../../../../../common/constants'; -import { machineLearningRuleParams, MachineLearningRuleParams } from '../../schemas/rule_schemas'; +import { MachineLearningRuleParams, machineLearningRuleParams } from '../../schemas/rule_schemas'; import { mlExecutor } from '../../signals/executors/ml'; -import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; -import { CreateRuleOptions } from '../types'; +import { CreateRuleOptions, SecurityAlertType } from '../types'; -export const createMlAlertType = (createOptions: CreateRuleOptions) => { - const { lists, logger, config, ml, ruleDataClient, eventLogService } = createOptions; - const createSecurityRuleType = createSecurityRuleTypeFactory({ - lists, - logger, - config, - ruleDataClient, - eventLogService, - }); - return createSecurityRuleType<MachineLearningRuleParams, {}, PersistenceServices, {}>({ +export const createMlAlertType = ( + createOptions: CreateRuleOptions +): SecurityAlertType<MachineLearningRuleParams, {}, {}, 'default'> => { + const { logger, ml } = createOptions; + return { id: ML_RULE_TYPE_ID, name: 'Machine Learning Rule', validate: { @@ -81,5 +74,5 @@ export const createMlAlertType = (createOptions: CreateRuleOptions) => { }); return { ...result, state }; }, - }); + }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts index 4fdeac8047b1d..638c40c13cfe2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts @@ -14,6 +14,7 @@ import { allowedExperimentalValues } from '../../../../../common/experimental_fe import { sampleDocNoSortId } from '../../signals/__mocks__/es_results'; import { createQueryAlertType } from './create_query_alert_type'; import { createRuleTypeMocks } from '../__mocks__/rule_type'; +import { createSecurityRuleTypeWrapper } from '../create_security_rule_type_wrapper'; import { createMockConfig } from '../../routes/__mocks__'; jest.mock('../utils/get_list_client', () => ({ @@ -26,17 +27,22 @@ jest.mock('../utils/get_list_client', () => ({ jest.mock('../../rule_execution_log/rule_execution_log_client'); describe('Custom Query Alerts', () => { + const { services, dependencies, executor } = createRuleTypeMocks(); + const securityRuleTypeWrapper = createSecurityRuleTypeWrapper({ + lists: dependencies.lists, + logger: dependencies.logger, + config: createMockConfig(), + ruleDataClient: dependencies.ruleDataClient, + eventLogService: dependencies.eventLogService, + }); it('does not send an alert when no events found', async () => { - const { services, dependencies, executor } = createRuleTypeMocks(); - const queryAlertType = createQueryAlertType({ - experimentalFeatures: allowedExperimentalValues, - lists: dependencies.lists, - logger: dependencies.logger, - config: createMockConfig(), - ruleDataClient: dependencies.ruleDataClient, - eventLogService: dependencies.eventLogService, - version: '1.0.0', - }); + const queryAlertType = securityRuleTypeWrapper( + createQueryAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(queryAlertType); @@ -74,16 +80,13 @@ describe('Custom Query Alerts', () => { }); it('sends a properly formatted alert when events are found', async () => { - const { services, dependencies, executor } = createRuleTypeMocks(); - const queryAlertType = createQueryAlertType({ - experimentalFeatures: allowedExperimentalValues, - lists: dependencies.lists, - logger: dependencies.logger, - config: createMockConfig(), - ruleDataClient: dependencies.ruleDataClient, - eventLogService: dependencies.eventLogService, - version: '1.0.0', - }); + const queryAlertType = securityRuleTypeWrapper( + createQueryAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); dependencies.alerting.registerType(queryAlertType); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts index 469c237112dcb..aa2b25c422221 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts @@ -6,24 +6,16 @@ */ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; -import { PersistenceServices } from '../../../../../../rule_registry/server'; import { QUERY_RULE_TYPE_ID } from '../../../../../common/constants'; -import { queryRuleParams, QueryRuleParams } from '../../schemas/rule_schemas'; +import { QueryRuleParams, queryRuleParams } from '../../schemas/rule_schemas'; import { queryExecutor } from '../../signals/executors/query'; -import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; -import { CreateRuleOptions } from '../types'; +import { CreateRuleOptions, SecurityAlertType } from '../types'; -export const createQueryAlertType = (createOptions: CreateRuleOptions) => { - const { experimentalFeatures, lists, logger, config, ruleDataClient, version, eventLogService } = - createOptions; - const createSecurityRuleType = createSecurityRuleTypeFactory({ - lists, - logger, - config, - ruleDataClient, - eventLogService, - }); - return createSecurityRuleType<QueryRuleParams, {}, PersistenceServices, {}>({ +export const createQueryAlertType = ( + createOptions: CreateRuleOptions +): SecurityAlertType<QueryRuleParams, {}, {}, 'default'> => { + const { experimentalFeatures, logger, version } = createOptions; + return { id: QUERY_RULE_TYPE_ID, name: 'Custom Query Rule', validate: { @@ -86,5 +78,5 @@ export const createQueryAlertType = (createOptions: CreateRuleOptions) => { }); return { ...result, state }; }, - }); + }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.test.ts index aff57dbdf3cd4..093ec0af78f59 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.test.ts @@ -9,6 +9,7 @@ import { allowedExperimentalValues } from '../../../../../common/experimental_fe import { createThresholdAlertType } from './create_threshold_alert_type'; import { createRuleTypeMocks } from '../__mocks__/rule_type'; import { getThresholdRuleParams } from '../../schemas/rule_schemas.mock'; +import { createSecurityRuleTypeWrapper } from '../create_security_rule_type_wrapper'; import { createMockConfig } from '../../routes/__mocks__'; jest.mock('../../rule_execution_log/rule_execution_log_client'); @@ -17,16 +18,21 @@ describe('Threshold Alerts', () => { it('does not send an alert when no events found', async () => { const params = getThresholdRuleParams(); const { dependencies, executor } = createRuleTypeMocks('threshold', params); - const thresholdAlertTpe = createThresholdAlertType({ - experimentalFeatures: allowedExperimentalValues, + const securityRuleTypeWrapper = createSecurityRuleTypeWrapper({ lists: dependencies.lists, logger: dependencies.logger, config: createMockConfig(), ruleDataClient: dependencies.ruleDataClient, eventLogService: dependencies.eventLogService, - version: '1.0.0', }); - dependencies.alerting.registerType(thresholdAlertTpe); + const thresholdAlertType = securityRuleTypeWrapper( + createThresholdAlertType({ + experimentalFeatures: allowedExperimentalValues, + logger: dependencies.logger, + version: '1.0.0', + }) + ); + dependencies.alerting.registerType(thresholdAlertType); await executor({ params }); expect(dependencies.ruleDataClient.getWriter).not.toBeCalled(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts index 789e4525c58ab..2b3c1c0a8965b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts @@ -6,26 +6,17 @@ */ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; - -import { PersistenceServices } from '../../../../../../rule_registry/server'; import { THRESHOLD_RULE_TYPE_ID } from '../../../../../common/constants'; import { thresholdRuleParams, ThresholdRuleParams } from '../../schemas/rule_schemas'; import { thresholdExecutor } from '../../signals/executors/threshold'; import { ThresholdAlertState } from '../../signals/types'; -import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; -import { CreateRuleOptions } from '../types'; +import { CreateRuleOptions, SecurityAlertType } from '../types'; -export const createThresholdAlertType = (createOptions: CreateRuleOptions) => { - const { experimentalFeatures, lists, logger, config, ruleDataClient, version, eventLogService } = - createOptions; - const createSecurityRuleType = createSecurityRuleTypeFactory({ - lists, - logger, - config, - ruleDataClient, - eventLogService, - }); - return createSecurityRuleType<ThresholdRuleParams, {}, PersistenceServices, ThresholdAlertState>({ +export const createThresholdAlertType = ( + createOptions: CreateRuleOptions +): SecurityAlertType<ThresholdRuleParams, ThresholdAlertState, {}, 'default'> => { + const { experimentalFeatures, logger, version } = createOptions; + return { id: THRESHOLD_RULE_TYPE_ID, name: 'Threshold Rule', validate: { @@ -63,8 +54,6 @@ export const createThresholdAlertType = (createOptions: CreateRuleOptions) => { state, } = execOptions; - // console.log(JSON.stringify(state)); - const result = await thresholdExecutor({ buildRuleMessage, bulkCreate, @@ -82,5 +71,5 @@ export const createThresholdAlertType = (createOptions: CreateRuleOptions) => { return result; }, - }); + }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts index c94339da03b93..393cb00939b24 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts @@ -11,28 +11,30 @@ import { SearchHit } from '@elastic/elasticsearch/api/types'; import { Logger } from '@kbn/logging'; import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { AlertExecutorOptions, AlertType } from '../../../../../alerting/server'; import { SavedObject } from '../../../../../../../src/core/server'; import { AlertInstanceContext, AlertInstanceState, - AlertTypeParams, AlertTypeState, + WithoutReservedActionGroups, } from '../../../../../alerting/common'; -import { AlertType } from '../../../../../alerting/server'; import { ListClient } from '../../../../../lists/server'; import { TechnicalRuleFieldMap } from '../../../../../rule_registry/common/assets/field_maps/technical_rule_field_map'; import { TypeOfFieldMap } from '../../../../../rule_registry/common/field_map'; -import { - AlertTypeWithExecutor, - PersistenceServices, - IRuleDataClient, -} from '../../../../../rule_registry/server'; +import { PersistenceServices, IRuleDataClient } from '../../../../../rule_registry/server'; import { BaseHit } from '../../../../common/detection_engine/types'; import { ConfigType } from '../../../config'; import { SetupPlugins } from '../../../plugin'; import { RuleParams } from '../schemas/rule_schemas'; import { BuildRuleMessage } from '../signals/rule_messages'; -import { AlertAttributes, BulkCreate, WrapHits, WrapSequences } from '../signals/types'; +import { + AlertAttributes, + BulkCreate, + SearchAfterAndBulkCreateReturnType, + WrapHits, + WrapSequences, +} from '../signals/types'; import { AlertsFieldMap, RulesFieldMap } from './field_maps'; import { ExperimentalFeatures } from '../../../../common/experimental_features'; import { IEventLogService } from '../../../../../event_log/server'; @@ -50,12 +52,6 @@ export interface SecurityAlertTypeReturnValue<TState extends AlertTypeState> { warningMessages: string[]; } -type SimpleAlertType< - TState extends AlertTypeState, - TParams extends AlertTypeParams = {}, - TAlertInstanceContext extends AlertInstanceContext = {} -> = AlertType<TParams, TParams, TState, AlertInstanceState, TAlertInstanceContext, string, string>; - export interface RunOpts<TParams extends RuleParams> { buildRuleMessage: BuildRuleMessage; bulkCreate: BulkCreate; @@ -72,44 +68,42 @@ export interface RunOpts<TParams extends RuleParams> { wrapSequences: WrapSequences; } -export type SecurityAlertTypeExecutor< - TState extends AlertTypeState, - TServices extends PersistenceServices<TAlertInstanceContext>, +export type SecurityAlertType< TParams extends RuleParams, - TAlertInstanceContext extends AlertInstanceContext = {} -> = ( - options: Parameters<SimpleAlertType<TState, TParams, TAlertInstanceContext>['executor']>[0] & { - runOpts: RunOpts<TParams>; - } & { services: TServices } -) => Promise<SecurityAlertTypeReturnValue<TState>>; - -type SecurityAlertTypeWithExecutor< TState extends AlertTypeState, - TServices extends PersistenceServices<TAlertInstanceContext>, - TParams extends RuleParams, - TAlertInstanceContext extends AlertInstanceContext = {} + TInstanceContext extends AlertInstanceContext = {}, + TActionGroupIds extends string = never > = Omit< - AlertType<TParams, TParams, TState, AlertInstanceState, TAlertInstanceContext, string, string>, + AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>, 'executor' > & { - executor: SecurityAlertTypeExecutor<TState, TServices, TParams, TAlertInstanceContext>; + executor: ( + options: AlertExecutorOptions< + TParams, + TState, + AlertInstanceState, + TInstanceContext, + WithoutReservedActionGroups<TActionGroupIds, never> + > & { + services: PersistenceServices; + runOpts: RunOpts<TParams>; + } + ) => Promise<SearchAfterAndBulkCreateReturnType & { state: TState }>; }; -export type CreateSecurityRuleTypeFactory = (options: { +export type CreateSecurityRuleTypeWrapper = (options: { lists: SetupPlugins['lists']; logger: Logger; config: ConfigType; ruleDataClient: IRuleDataClient; eventLogService: IEventLogService; }) => < - TParams extends RuleParams & { index?: string[] | undefined }, - TAlertInstanceContext extends AlertInstanceContext, - TServices extends PersistenceServices<TAlertInstanceContext>, - TState extends AlertTypeState + TParams extends RuleParams, + TState extends AlertTypeState, + TInstanceContext extends AlertInstanceContext = {} >( - type: SecurityAlertTypeWithExecutor<TState, TServices, TParams, TAlertInstanceContext> - // eslint-disable-next-line @typescript-eslint/no-explicit-any -) => AlertTypeWithExecutor<TState, TParams, TAlertInstanceContext, any>; + type: SecurityAlertType<TParams, TState, TInstanceContext, 'default'> +) => AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, 'default'>; export type RACAlertSignal = TypeOfFieldMap<AlertsFieldMap> & TypeOfFieldMap<RulesFieldMap>; export type RACAlert = Exclude< @@ -124,11 +118,7 @@ export type WrappedRACAlert = BaseHit<RACAlert>; export interface CreateRuleOptions { experimentalFeatures: ExperimentalFeatures; - lists: SetupPlugins['lists']; logger: Logger; - config: ConfigType; ml?: SetupPlugins['ml']; - ruleDataClient: IRuleDataClient; version: string; - eventLogService: IEventLogService; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts index f44471e6e26f9..71079ccefc97a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts @@ -5,11 +5,12 @@ * 2.0. */ +import { transformDataToNdjson } from '@kbn/securitysolution-utils'; + import { RulesClient } from '../../../../../alerting/server'; import { getNonPackagedRules } from './get_existing_prepackaged_rules'; import { getExportDetailsNdjson } from './get_export_details_ndjson'; import { transformAlertsToRules } from '../routes/rules/utils'; -import { transformDataToNdjson } from '../../../utils/read_stream/create_stream_from_ndjson'; export const getExportAll = async ( rulesClient: RulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts index 31a7604306de7..4cf3ad9133a71 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts @@ -6,13 +6,13 @@ */ import { chunk } from 'lodash'; +import { transformDataToNdjson } from '@kbn/securitysolution-utils'; import { RulesSchema } from '../../../../common/detection_engine/schemas/response/rules_schema'; import { RulesClient } from '../../../../../alerting/server'; import { getExportDetailsNdjson } from './get_export_details_ndjson'; import { isAlertType } from '../rules/types'; import { transformAlertToRule } from '../routes/rules/utils'; -import { transformDataToNdjson } from '../../../utils/read_stream/create_stream_from_ndjson'; import { INTERNAL_RULE_ID_KEY } from '../../../../common/constants'; import { findRules } from './find_rules'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json index 25ad15f1b0a51..6e2073bbb82b6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json @@ -42,7 +42,14 @@ { "id": "T1114", "name": "Email Collection", - "reference": "https://attack.mitre.org/techniques/T1114/" + "reference": "https://attack.mitre.org/techniques/T1114/", + "subtechnique": [ + { + "id": "T1114.002", + "name": "Remote Email Collection", + "reference": "https://attack.mitre.org/techniques/T1114/002/" + } + ] }, { "id": "T1005", @@ -54,5 +61,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json index 73c4300556a02..fa0ee2b18bb15 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json @@ -38,12 +38,19 @@ { "id": "T1560", "name": "Archive Collected Data", - "reference": "https://attack.mitre.org/techniques/T1560/" + "reference": "https://attack.mitre.org/techniques/T1560/", + "subtechnique": [ + { + "id": "T1560.001", + "name": "Archive via Utility", + "reference": "https://attack.mitre.org/techniques/T1560/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json index 0d80e78c556b9..b1774ab3dd052 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json @@ -38,9 +38,36 @@ "reference": "https://attack.mitre.org/techniques/T1102/" } ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0010", + "name": "Exfiltration", + "reference": "https://attack.mitre.org/tactics/TA0010/" + }, + "technique": [ + { + "id": "T1567", + "name": "Exfiltration Over Web Service", + "reference": "https://attack.mitre.org/techniques/T1567/", + "subtechnique": [ + { + "id": "T1567.001", + "name": "Exfiltration to Code Repository", + "reference": "https://attack.mitre.org/techniques/T1567/001/" + }, + { + "id": "T1567.002", + "name": "Exfiltration to Cloud Storage", + "reference": "https://attack.mitre.org/techniques/T1567/002/" + } + ] + } + ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json index 8567b18670301..f57bd65b6d992 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_directly_to_the_internet.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "This rule detects when an internal network client sends DNS traffic directly to the Internet. This is atypical behavior for a managed network and can be indicative of malware, exfiltration, command and control, or simply misconfiguration. This DNS activity also impacts your organization's ability to provide enterprise monitoring and logging of DNS and it opens your network to a variety of abuses and malicious communications.", + "description": "This rule detects when an internal network client sends DNS traffic directly to the Internet. This is atypical behavior for a managed network and can be indicative of malware, exfiltration, command and control, or simply misconfiguration. This DNS activity also impacts your organization's ability to provide enterprise monitoring and logging of DNS, and it opens your network to a variety of abuses and malicious communications.", "false_positives": [ "Exclude DNS servers from this rule as this is expected behavior. Endpoints usually query local DNS servers defined in their DHCP scopes, but this may be overridden if a user configures their endpoint to use a remote DNS server. This is uncommon in managed enterprise networks because it could break intranet name resolution when split horizon DNS is utilized. Some consumer VPN services and browser plug-ins may send DNS traffic to remote Internet destinations. In that case, such devices or networks can be excluded from this rule when this is expected behavior." ], @@ -45,5 +45,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 11 + "version": 12 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json index 0920f336bab44..29c30f6bc0b49 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json @@ -38,7 +38,14 @@ { "id": "T1071", "name": "Application Layer Protocol", - "reference": "https://attack.mitre.org/techniques/T1071/" + "reference": "https://attack.mitre.org/techniques/T1071/", + "subtechnique": [ + { + "id": "T1071.004", + "name": "DNS", + "reference": "https://attack.mitre.org/techniques/T1071/004/" + } + ] } ] } @@ -50,5 +57,5 @@ "value": 15 }, "type": "threshold", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json index 0bcbb0d2d031d..dcca38dd242d8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "Detects a Roshal Archive (RAR) file or PowerShell script downloaded from the internet by an internal host. Gaining initial access to a system and then downloading encoded or encrypted tools to move laterally is a common practice for adversaries as a way to protect their more valuable tools and TTPs (tactics, techniques, and procedures). This may be atypical behavior for a managed network and can be indicative of malware, exfiltration, or command and control.", + "description": "Detects a Roshal Archive (RAR) file or PowerShell script downloaded from the internet by an internal host. Gaining initial access to a system and then downloading encoded or encrypted tools to move laterally is a common practice for adversaries as a way to protect their more valuable tools and tactics, techniques, and procedures (TTPs). This may be atypical behavior for a managed network and can be indicative of malware, exfiltration, or command and control.", "false_positives": [ "Downloading RAR or PowerShell files from the Internet may be expected for certain systems. This rule should be tailored to either exclude systems as sources or destinations in which this behavior is expected." ], @@ -52,5 +52,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 7 + "version": 8 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json index 2cfbbc1c5e101..d0039ab4f02d4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json @@ -41,8 +41,30 @@ "reference": "https://attack.mitre.org/techniques/T1071/" } ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, + "technique": [ + { + "id": "T1559", + "name": "Inter-Process Communication", + "reference": "https://attack.mitre.org/techniques/T1559/", + "subtechnique": [ + { + "id": "T1559.001", + "name": "Component Object Model", + "reference": "https://attack.mitre.org/techniques/T1559/001/" + } + ] + } + ] } ], "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json similarity index 66% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json index cb5c8e87dcae8..65612e6c28f20 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_port_forwarding_added_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json @@ -24,33 +24,26 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Command and Control" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0011", + "name": "Command and Control", + "reference": "https://attack.mitre.org/tactics/TA0011/" }, "technique": [ { - "id": "T1562", - "name": "Impair Defenses", - "reference": "https://attack.mitre.org/techniques/T1562/", - "subtechnique": [ - { - "id": "T1562.001", - "name": "Disable or Modify Tools", - "reference": "https://attack.mitre.org/techniques/T1562/001/" - } - ] + "id": "T1572", + "name": "Protocol Tunneling", + "reference": "https://attack.mitre.org/techniques/T1572/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_tunnel_plink.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json similarity index 69% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_tunnel_plink.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json index dd6bdfa0c37d6..3c89ff7c9ff9a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_tunnel_plink.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "Identifies potential use of an SSH utility to establish RDP over a reverse SSH Tunnel. This could be indicative of adversary lateral movement to interactively access restricted networks.", + "description": "Identifies potential use of an SSH utility to establish RDP over a reverse SSH Tunnel. This can be used by attackers to enable routing of network packets that would otherwise not reach their intended destination.", "from": "now-9m", "index": [ "logs-endpoint.events.*", @@ -24,26 +24,26 @@ "Host", "Windows", "Threat Detection", - "Lateral Movement" + "Command and Control" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0008", - "name": "Lateral Movement", - "reference": "https://attack.mitre.org/tactics/TA0008/" + "id": "TA0011", + "name": "Command and Control", + "reference": "https://attack.mitre.org/tactics/TA0011/" }, "technique": [ { - "id": "T1021", - "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" + "id": "T1572", + "name": "Protocol Tunneling", + "reference": "https://attack.mitre.org/techniques/T1572/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json index 428b08891c15a..eed29634daeef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote File Download via Script Interpreter", - "query": "sequence by host.id, process.entity_id\n [network where process.name : (\"wscript.exe\", \"cscript.exe\") and network.protocol != \"dns\" and\n network.direction == \"outgoing\" and network.type == \"ipv4\" and destination.ip != \"127.0.0.1\"\n ]\n [file where event.type == \"creation\" and file.extension : (\"exe\", \"dll\")]\n", + "query": "sequence by host.id, process.entity_id\n [network where process.name : (\"wscript.exe\", \"cscript.exe\") and network.protocol != \"dns\" and\n network.direction : (\"outgoing\", \"egress\") and network.type == \"ipv4\" and destination.ip != \"127.0.0.1\"\n ]\n [file where event.type == \"creation\" and file.extension : (\"exe\", \"dll\")]\n", "risk_score": 47, "rule_id": "1d276579-3380-4095-ad38-e596a01bc64f", "severity": "medium", @@ -41,5 +41,5 @@ } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json index 08d4df2556f6a..a1f0f061a69bc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json @@ -39,11 +39,16 @@ "id": "T1105", "name": "Ingress Tool Transfer", "reference": "https://attack.mitre.org/techniques/T1105/" + }, + { + "id": "T1219", + "name": "Remote Access Software", + "reference": "https://attack.mitre.org/techniques/T1219/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json index 32c271f736e4a..9671f3c4edf2a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json @@ -38,12 +38,24 @@ { "id": "T1003", "name": "OS Credential Dumping", - "reference": "https://attack.mitre.org/techniques/T1003/" + "reference": "https://attack.mitre.org/techniques/T1003/", + "subtechnique": [ + { + "id": "T1003.001", + "name": "LSASS Memory", + "reference": "https://attack.mitre.org/techniques/T1003/001/" + }, + { + "id": "T1003.003", + "name": "NTDS", + "reference": "https://attack.mitre.org/techniques/T1003/003/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json index 91613078c6167..0aeba88224138 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json @@ -41,12 +41,19 @@ { "id": "T1003", "name": "OS Credential Dumping", - "reference": "https://attack.mitre.org/techniques/T1003/" + "reference": "https://attack.mitre.org/techniques/T1003/", + "subtechnique": [ + { + "id": "T1003.002", + "name": "Security Account Manager", + "reference": "https://attack.mitre.org/techniques/T1003/002/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json index c031fcbf464b1..43ea1078d1583 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json @@ -48,11 +48,16 @@ "reference": "https://attack.mitre.org/techniques/T1552/004/" } ] + }, + { + "id": "T1555", + "name": "Credentials from Password Stores", + "reference": "https://attack.mitre.org/techniques/T1555/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json index c3868162cc839..10c6996fa56aa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json @@ -38,12 +38,24 @@ { "id": "T1003", "name": "OS Credential Dumping", - "reference": "https://attack.mitre.org/techniques/T1003/" + "reference": "https://attack.mitre.org/techniques/T1003/", + "subtechnique": [ + { + "id": "T1003.002", + "name": "Security Account Manager", + "reference": "https://attack.mitre.org/techniques/T1003/002/" + }, + { + "id": "T1003.004", + "name": "LSA Secrets", + "reference": "https://attack.mitre.org/techniques/T1003/004/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json index b05ddd7bcc8a2..8fc7cd7b379b8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Kerberos Traffic from Unusual Process", - "query": "network where event.type == \"start\" and network.direction == \"outgoing\" and\n destination.port == 88 and source.port >= 49152 and\n process.executable != \"C:\\\\Windows\\\\System32\\\\lsass.exe\" and destination.address !=\"127.0.0.1\" and destination.address !=\"::1\" and\n /* insert False Positives here */\n not process.name in (\"swi_fc.exe\", \"fsIPcam.exe\", \"IPCamera.exe\", \"MicrosoftEdgeCP.exe\", \"MicrosoftEdge.exe\", \"iexplore.exe\", \"chrome.exe\", \"msedge.exe\", \"opera.exe\", \"firefox.exe\")\n", + "query": "network where event.type == \"start\" and network.direction : (\"outgoing\", \"egress\") and\n destination.port == 88 and source.port >= 49152 and\n process.executable != \"C:\\\\Windows\\\\System32\\\\lsass.exe\" and destination.address !=\"127.0.0.1\" and destination.address !=\"::1\" and\n /* insert False Positives here */\n not process.name in (\"swi_fc.exe\", \"fsIPcam.exe\", \"IPCamera.exe\", \"MicrosoftEdgeCP.exe\", \"MicrosoftEdge.exe\", \"iexplore.exe\", \"chrome.exe\", \"msedge.exe\", \"opera.exe\", \"firefox.exe\")\n", "risk_score": 47, "rule_id": "897dc6b5-b39f-432a-8d75-d3730d50c782", "severity": "medium", @@ -45,5 +45,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberosdump_kcc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberosdump_kcc.json index de5a9d80ed3df..3338895f30feb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberosdump_kcc.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberosdump_kcc.json @@ -39,11 +39,23 @@ "id": "T1003", "name": "OS Credential Dumping", "reference": "https://attack.mitre.org/techniques/T1003/" + }, + { + "id": "T1558", + "name": "Steal or Forge Kerberos Tickets", + "reference": "https://attack.mitre.org/techniques/T1558/", + "subtechnique": [ + { + "id": "T1558.003", + "name": "Kerberoasting", + "reference": "https://attack.mitre.org/techniques/T1558/003/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json index 36b614c628b19..d083fb322e895 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json @@ -39,12 +39,19 @@ { "id": "T1003", "name": "OS Credential Dumping", - "reference": "https://attack.mitre.org/techniques/T1003/" + "reference": "https://attack.mitre.org/techniques/T1003/", + "subtechnique": [ + { + "id": "T1003.001", + "name": "LSASS Memory", + "reference": "https://attack.mitre.org/techniques/T1003/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json new file mode 100644 index 0000000000000..1024d7f3461f5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json @@ -0,0 +1,55 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies suspicious access to an LSASS handle via DuplicateHandle from an unknown call trace module. This may indicate an attempt to bypass the NtOpenProcess API to evade detection and dump Lsass memory for credential access.", + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-windows.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Potential Credential Access via DuplicateHandle in LSASS", + "query": "process where event.code == \"10\" and \n\n /* LSASS requesting DuplicateHandle access right to another process */\n process.name : \"lsass.exe\" and winlog.event_data.GrantedAccess == \"0x40\" and\n\n /* call is coming from an unknown executable region */\n winlog.event_data.CallTrace : \"*UNKNOWN*\"\n", + "references": [ + "https://github.com/CCob/MirrorDump" + ], + "risk_score": 47, + "rule_id": "02a4576a-7480-4284-9327-548a806b5e48", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Credential Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0006", + "name": "Credential Access", + "reference": "https://attack.mitre.org/tactics/TA0006/" + }, + "technique": [ + { + "id": "T1003", + "name": "OS Credential Dumping", + "reference": "https://attack.mitre.org/techniques/T1003/", + "subtechnique": [ + { + "id": "T1003.001", + "name": "LSASS Memory", + "reference": "https://attack.mitre.org/techniques/T1003/001/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vaultcmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vaultcmd.json index bfb4e44d39b0d..c6db4426ac8c1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vaultcmd.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vaultcmd.json @@ -40,11 +40,23 @@ "id": "T1003", "name": "OS Credential Dumping", "reference": "https://attack.mitre.org/techniques/T1003/" + }, + { + "id": "T1555", + "name": "Credentials from Password Stores", + "reference": "https://attack.mitre.org/techniques/T1555/", + "subtechnique": [ + { + "id": "T1555.004", + "name": "Windows Credential Manager", + "reference": "https://attack.mitre.org/techniques/T1555/004/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json index 79e059d68a52a..2759055b0fe5b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json @@ -35,12 +35,19 @@ { "id": "T1070", "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/" + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.001", + "name": "Clear Windows Event Logs", + "reference": "https://attack.mitre.org/techniques/T1070/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 9 + "version": 10 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json index d04c2b2a38915..eedca883e371c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json @@ -7,7 +7,8 @@ "from": "now-9m", "index": [ "winlogbeat-*", - "logs-windows.*" + "logs-windows.*", + "logs-system.*" ], "language": "kuery", "license": "Elastic License v2", @@ -35,12 +36,19 @@ { "id": "T1070", "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/" + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.001", + "name": "Clear Windows Event Logs", + "reference": "https://attack.mitre.org/techniques/T1070/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json index 000384eac660e..716040d337c10 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Windows Defender Exclusions Added via PowerShell", - "note": "## Triage and analysis\n\nDetections should be investigated to identify if the activity corresponds to legitimate activity used to put in exceptions for Windows Defender. As this rule detects post-exploitation process activity, investigations into this should be prioritized.", + "note": "## Triage and analysis\n\n### Investigating Windows Defender Exclusions\n\nMicrosoft Windows Defender is an anti-virus product built-in within Microsoft Windows. Since this software product is\nused to prevent and stop malware, it's important to monitor what specific exclusions are made to the product's configuration\nsettings. These can often be signs of an adversary or malware trying to bypass Windows Defender's capabilities. One of the more\nnotable [examples](https://www.cyberbit.com/blog/endpoint-security/latest-trickbot-variant-has-new-tricks-up-its-sleeve/) was observed in 2018 where Trickbot incorporated mechanisms to disable Windows Defense to avoid detection.\n\n#### Possible investigation steps:\n- With this specific rule, it's completely possible to trigger detections on network administrative activity or benign users\nusing scripting and PowerShell to configure the different exclusions for Windows Defender. Therefore, it's important to\nidentify the source of the activity first and determine if there is any mal-intent behind the events.\n- The actual exclusion such as the process, the file or directory should be reviewed in order to determine the original\nintent behind the exclusion. Is the excluded file or process malicious in nature or is it related to software that needs\nto be legitimately whitelisted from Windows Defender?\n\n### False Positive Analysis\n- This rule has a higher chance to produce false positives based on the nature around configuring exclusions by possibly\na network administrator. In order to validate the activity further, review the specific exclusion made and determine based\non the exclusion of the original intent behind the exclusion. There are often many legitimate reasons why exclusions are made\nwith Windows Defender so it's important to gain context around the exclusion.\n\n### Related Rules\n- Windows Defender Disabled via Registry Modification\n- Disabling Windows Defender Security Settings via PowerShell\n\n### Response and Remediation\n- Since this is related to post-exploitation activity, immediate response should be taken to review, investigate and\npotentially isolate further activity\n- If further analysis showed malicious intent was behind the Defender exclusions, administrators should remove\nthe exclusion and ensure antimalware capability has not been disabled or deleted\n- Exclusion lists for antimalware capabilities should always be routinely monitored for review\n", "query": "process where event.type == \"start\" and\n (process.name : (\"powershell.exe\", \"pwsh.exe\") or process.pe.original_file_name : (\"powershell.exe\", \"pwsh.exe\")) and\n process.args : (\"*Add-MpPreference*-Exclusion*\", \"*Set-MpPreference*-Exclusion*\")\n", "references": [ "https://www.bitdefender.com/files/News/CaseStudies/study/400/Bitdefender-PR-Whitepaper-MosaicLoader-creat5540-en-EN.pdf" @@ -80,5 +80,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json index 00f18df34f864..2e18f3ba62786 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json @@ -38,9 +38,9 @@ "reference": "https://attack.mitre.org/techniques/T1562/", "subtechnique": [ { - "id": "T1562.001", - "name": "Disable or Modify Tools", - "reference": "https://attack.mitre.org/techniques/T1562/001/" + "id": "T1562.004", + "name": "Disable or Modify System Firewall", + "reference": "https://attack.mitre.org/techniques/T1562/004/" } ] } @@ -49,5 +49,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 9 + "version": 10 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json index d2612101a3e4c..256d1c7d9c135 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json @@ -40,12 +40,19 @@ { "id": "T1070", "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/" + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.001", + "name": "Clear Windows Event Logs", + "reference": "https://attack.mitre.org/techniques/T1070/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json index 4588a8ab28657..e8edb8fba6472 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json @@ -33,14 +33,21 @@ }, "technique": [ { - "id": "T1055", - "name": "Process Injection", - "reference": "https://attack.mitre.org/techniques/T1055/" + "id": "T1027", + "name": "Obfuscated Files or Information", + "reference": "https://attack.mitre.org/techniques/T1027/", + "subtechnique": [ + { + "id": "T1027.004", + "name": "Compile After Delivery", + "reference": "https://attack.mitre.org/techniques/T1027/004/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json new file mode 100644 index 0000000000000..5685ac76b3ef9 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json @@ -0,0 +1,61 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies when an ElastiCache security group has been created.", + "false_positives": [ + "A ElastiCache security group may be created by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Security group creations from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "from": "now-60m", + "index": [ + "filebeat-*", + "logs-aws*" + ], + "interval": "10m", + "language": "kuery", + "license": "Elastic License v2", + "name": "AWS ElastiCache Security Group Created", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:aws.cloudtrail and event.provider:elasticache.amazonaws.com and event.action:\"Create Cache Security Group\" and \nevent.outcome:success\n", + "references": [ + "https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateCacheSecurityGroup.html" + ], + "risk_score": 21, + "rule_id": "7b3da11a-60a2-412e-8aa7-011e1eb9ed47", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "AWS", + "Continuous Monitoring", + "SecOps", + "Monitoring" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.007", + "name": "Disable or Modify Cloud Firewall", + "reference": "https://attack.mitre.org/techniques/T1562/007/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json new file mode 100644 index 0000000000000..83b58c0c046e0 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json @@ -0,0 +1,61 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies when an ElastiCache security group has been modified or deleted.", + "false_positives": [ + "A ElastiCache security group deletion may be done by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Security Group deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "from": "now-60m", + "index": [ + "filebeat-*", + "logs-aws*" + ], + "interval": "10m", + "language": "kuery", + "license": "Elastic License v2", + "name": "AWS ElastiCache Security Group Modified or Deleted", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:aws.cloudtrail and event.provider:elasticache.amazonaws.com and event.action:(\"Delete Cache Security Group\" or \n\"Authorize Cache Security Group Ingress\" or \"Revoke Cache Security Group Ingress\" or \"AuthorizeCacheSecurityGroupEgress\" or \n\"RevokeCacheSecurityGroupEgress\") and event.outcome:success\n", + "references": [ + "https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/Welcome.html" + ], + "risk_score": 21, + "rule_id": "1ba5160d-f5a2-4624-b0ff-6a1dc55d2516", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "AWS", + "Continuous Monitoring", + "SecOps", + "Monitoring" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.007", + "name": "Disable or Modify Cloud Firewall", + "reference": "https://attack.mitre.org/techniques/T1562/007/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json index 93454122d1160..e6b53af71433a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json @@ -38,9 +38,9 @@ "reference": "https://attack.mitre.org/techniques/T1562/", "subtechnique": [ { - "id": "T1562.001", - "name": "Disable or Modify Tools", - "reference": "https://attack.mitre.org/techniques/T1562/001/" + "id": "T1562.004", + "name": "Disable or Modify System Firewall", + "reference": "https://attack.mitre.org/techniques/T1562/004/" } ] } @@ -49,5 +49,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json index 5fcbec498a177..bf688fd74ce14 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json @@ -41,9 +41,9 @@ "reference": "https://attack.mitre.org/techniques/T1562/", "subtechnique": [ { - "id": "T1562.001", - "name": "Disable or Modify Tools", - "reference": "https://attack.mitre.org/techniques/T1562/001/" + "id": "T1562.004", + "name": "Disable or Modify System Firewall", + "reference": "https://attack.mitre.org/techniques/T1562/004/" } ] } @@ -52,5 +52,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json new file mode 100644 index 0000000000000..787e61cfe25c4 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json @@ -0,0 +1,56 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies unusual instances of Control Panel with suspicious keywords or paths in the process command line value. Adversaries may abuse Control.exe to proxy execution of malicious code.", + "from": "now-9m", + "index": [ + "logs-endpoint.events.*", + "winlogbeat-*", + "logs-windows.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Control Panel Process with Unusual Arguments", + "query": "process where event.type in (\"start\", \"process_started\") and\n process.executable : (\"?:\\\\Windows\\\\SysWOW64\\\\control.exe\", \"?:\\\\Windows\\\\System32\\\\control.exe\") and\n process.command_line :\n (\"*.jpg*\",\n \"*.png*\",\n \"*.gif*\",\n \"*.bmp*\",\n \"*.jpeg*\",\n \"*.TIFF*\",\n \"*.inf*\",\n \"*.dat*\",\n \"*.cpl:*/*\",\n \"*../../..*\",\n \"*/AppData/Local/*\",\n \"*:\\\\Users\\\\Public\\\\*\",\n \"*\\\\AppData\\\\Local\\\\*\")\n", + "references": [ + "https://www.joesandbox.com/analysis/476188/1/html" + ], + "risk_score": 73, + "rule_id": "416697ae-e468-4093-a93d-59661fa619ec", + "severity": "high", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Defense Evasion" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.002", + "name": "Control Panel", + "reference": "https://attack.mitre.org/techniques/T1218/002/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json index d56c90552d457..0ad45f03a0499 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json @@ -41,7 +41,14 @@ { "id": "T1127", "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" + "reference": "https://attack.mitre.org/techniques/T1127/", + "subtechnique": [ + { + "id": "T1127.001", + "name": "MSBuild", + "reference": "https://attack.mitre.org/techniques/T1127/001/" + } + ] } ] }, @@ -57,5 +64,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json index 3b640d8757b51..60b2a8f50c3f4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json @@ -38,7 +38,14 @@ { "id": "T1127", "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" + "reference": "https://attack.mitre.org/techniques/T1127/", + "subtechnique": [ + { + "id": "T1127.001", + "name": "MSBuild", + "reference": "https://attack.mitre.org/techniques/T1127/001/" + } + ] } ] }, @@ -54,5 +61,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json index 33094a88af313..fdee8ee548218 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json @@ -38,7 +38,14 @@ { "id": "T1127", "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" + "reference": "https://attack.mitre.org/techniques/T1127/", + "subtechnique": [ + { + "id": "T1127.001", + "name": "MSBuild", + "reference": "https://attack.mitre.org/techniques/T1127/001/" + } + ] } ] }, @@ -54,5 +61,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json index 43051cb8b27c9..a22594083bedb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json @@ -38,12 +38,19 @@ { "id": "T1036", "name": "Masquerading", - "reference": "https://attack.mitre.org/techniques/T1036/" + "reference": "https://attack.mitre.org/techniques/T1036/", + "subtechnique": [ + { + "id": "T1036.003", + "name": "Rename System Utilities", + "reference": "https://attack.mitre.org/techniques/T1036/003/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json index 7812dee8235ca..826d55f3b1882 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json @@ -1,6 +1,7 @@ { "author": [ - "Elastic" + "Elastic", + "Dennis Perto" ], "description": "Identifies a Windows trusted program that is known to be vulnerable to DLL Search Order Hijacking starting after being renamed or from a non-standard path. This is uncommon behavior and may indicate an attempt to evade defenses via side-loading a malicious DLL within the memory space of one of those processes.", "false_positives": [ @@ -15,7 +16,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential DLL Side-Loading via Microsoft Antimalware Service Executable", - "query": "process where event.type == \"start\" and\n (process.pe.original_file_name == \"MsMpEng.exe\" and not process.name : \"MsMpEng.exe\") or\n (process.name : \"MsMpEng.exe\" and not\n process.executable : (\"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\*.exe\",\n \"?:\\\\Program Files\\\\Windows Defender\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\Windows Defender\\\\*.exe\"))\n", + "query": "process where event.type == \"start\" and\n (process.pe.original_file_name == \"MsMpEng.exe\" and not process.name : \"MsMpEng.exe\") or\n (process.name : \"MsMpEng.exe\" and not\n process.executable : (\"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\*.exe\",\n \"?:\\\\Program Files\\\\Windows Defender\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\Windows Defender\\\\*.exe\",\n \"?:\\\\Program Files\\\\Microsoft Security Client\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\Microsoft Security Client\\\\*.exe\"))\n", "references": [ "https://news.sophos.com/en-us/2021/07/04/independence-day-revil-uses-supply-chain-exploit-to-attack-hundreds-of-businesses/" ], @@ -55,5 +56,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_creation_mult_extension.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_creation_mult_extension.json index 24cbb1e41dad6..4cbfb8bbbce6c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_creation_mult_extension.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_creation_mult_extension.json @@ -45,9 +45,31 @@ ] } ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0002", + "name": "Execution", + "reference": "https://attack.mitre.org/tactics/TA0002/" + }, + "technique": [ + { + "id": "T1204", + "name": "User Execution", + "reference": "https://attack.mitre.org/techniques/T1204/", + "subtechnique": [ + { + "id": "T1204.002", + "name": "Malicious File", + "reference": "https://attack.mitre.org/techniques/T1204/002/" + } + ] + } + ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json new file mode 100644 index 0000000000000..c443d45dde4f0 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json @@ -0,0 +1,60 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies the deletion of a Frontdoor Web Application Firewall (WAF) Policy in Azure. An adversary may delete a Frontdoor Web Application Firewall (WAF) Policy in an attempt to evade defenses and/or to eliminate barriers in carrying out their initiative.", + "false_positives": [ + "Azure Front Web Application Firewall (WAF) Policy deletions may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Azure Front Web Application Firewall (WAF) Policy deletions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "from": "now-25m", + "index": [ + "filebeat-*", + "logs-azure*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "Azure Frontdoor Web Application Firewall (WAF) Policy Deleted", + "note": "## Config\n\nThe Azure Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:azure.activitylogs and azure.activitylogs.operation_name:\"MICROSOFT.NETWORK/FRONTDOORWEBAPPLICATIONFIREWALLPOLICIES/DELETE\" and event.outcome:(Success or success)\n", + "references": [ + "https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#networking" + ], + "risk_score": 21, + "rule_id": "09d028a5-dcde-409f-8ae0-557cef1b7082", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "Azure", + "Continuous Monitoring", + "SecOps", + "Network Security" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json index 006f95054d047..c40bbf236d668 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json @@ -36,11 +36,16 @@ "id": "T1140", "name": "Deobfuscate/Decode Files or Information", "reference": "https://attack.mitre.org/techniques/T1140/" + }, + { + "id": "T1112", + "name": "Modify Registry", + "reference": "https://attack.mitre.org/techniques/T1112/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json index 16de1c9c21f97..da12646d40226 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json @@ -34,14 +34,21 @@ }, "technique": [ { - "id": "T1070", - "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.002", + "name": "Disable Windows Event Logging", + "reference": "https://attack.mitre.org/techniques/T1562/002/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json index 4917cffd64ccb..72ef939fd2c1c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "InstallUtil Process Making Network Connections", - "query": "/* the benefit of doing this as an eql sequence vs kql is this will limit to alerting only on the first network connection */\n\nsequence by process.entity_id\n [process where event.type in (\"start\", \"process_started\") and process.name : \"installutil.exe\"]\n [network where process.name : \"installutil.exe\" and network.direction == \"outgoing\"]\n", + "query": "/* the benefit of doing this as an eql sequence vs kql is this will limit to alerting only on the first network connection */\n\nsequence by process.entity_id\n [process where event.type in (\"start\", \"process_started\") and process.name : \"installutil.exe\"]\n [network where process.name : \"installutil.exe\" and network.direction : (\"outgoing\", \"egress\")]\n", "risk_score": 21, "rule_id": "a13167f1-eec2-4015-9631-1fee60406dcf", "severity": "medium", @@ -48,5 +48,5 @@ } ], "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json index bd0a3ac9f918d..5c855207dda7d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json @@ -35,12 +35,19 @@ { "id": "T1036", "name": "Masquerading", - "reference": "https://attack.mitre.org/techniques/T1036/" + "reference": "https://attack.mitre.org/techniques/T1036/", + "subtechnique": [ + { + "id": "T1036.003", + "name": "Rename System Utilities", + "reference": "https://attack.mitre.org/techniques/T1036/003/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json index b0d11121c1a15..7ac21a70100c0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json @@ -35,12 +35,19 @@ { "id": "T1036", "name": "Masquerading", - "reference": "https://attack.mitre.org/techniques/T1036/" + "reference": "https://attack.mitre.org/techniques/T1036/", + "subtechnique": [ + { + "id": "T1036.005", + "name": "Match Legitimate Name or Location", + "reference": "https://attack.mitre.org/techniques/T1036/005/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_werfault.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_werfault.json index 2733bf992838e..a08e3040c6c95 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_werfault.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_werfault.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential Windows Error Manager Masquerading", - "query": "sequence by host.id, process.entity_id with maxspan = 5s\n [process where event.type:\"start\" and process.name : (\"wermgr.exe\", \"WerFault.exe\") and process.args_count == 1]\n [network where process.name : (\"wermgr.exe\", \"WerFault.exe\") and network.protocol != \"dns\" and\n network.direction == \"outgoing\" and destination.ip !=\"::1\" and destination.ip !=\"127.0.0.1\"\n ]\n", + "query": "sequence by host.id, process.entity_id with maxspan = 5s\n [process where event.type:\"start\" and process.name : (\"wermgr.exe\", \"WerFault.exe\") and process.args_count == 1]\n [network where process.name : (\"wermgr.exe\", \"WerFault.exe\") and network.protocol != \"dns\" and\n network.direction : (\"outgoing\", \"egress\") and destination.ip !=\"::1\" and destination.ip !=\"127.0.0.1\"\n ]\n", "references": [ "https://twitter.com/SBousseaden/status/1235533224337641473", "https://www.hexacorn.com/blog/2019/09/20/werfault-command-line-switches-v0-1/", @@ -49,5 +49,5 @@ } ], "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json index a2019165f93c6..6d0110c229c33 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json @@ -35,11 +35,18 @@ { "id": "T1127", "name": "Trusted Developer Utilities Proxy Execution", - "reference": "https://attack.mitre.org/techniques/T1127/" + "reference": "https://attack.mitre.org/techniques/T1127/", + "subtechnique": [ + { + "id": "T1127.001", + "name": "MSBuild", + "reference": "https://attack.mitre.org/techniques/T1127/001/" + } + ] } ] } ], "type": "eql", - "version": 7 + "version": 8 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json index b7d65b2336001..85316f7836b89 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json @@ -33,11 +33,18 @@ { "id": "T1070", "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/" + "reference": "https://attack.mitre.org/techniques/T1070/", + "subtechnique": [ + { + "id": "T1070.004", + "name": "File Deletion", + "reference": "https://attack.mitre.org/techniques/T1070/004/" + } + ] } ] } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json index 196a3de9b9e6f..f926a1ba24faf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json @@ -35,12 +35,19 @@ { "id": "T1564", "name": "Hide Artifacts", - "reference": "https://attack.mitre.org/techniques/T1564/" + "reference": "https://attack.mitre.org/techniques/T1564/", + "subtechnique": [ + { + "id": "T1564.004", + "name": "NTFS File Attributes", + "reference": "https://attack.mitre.org/techniques/T1564/004/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json index 51d1789804548..c0d171739b76d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json @@ -33,14 +33,21 @@ }, "technique": [ { - "id": "T1222", - "name": "File and Directory Permissions Modification", - "reference": "https://attack.mitre.org/techniques/T1222/" + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.001", + "name": "Disable or Modify Tools", + "reference": "https://attack.mitre.org/techniques/T1562/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 7 + "version": 8 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_whitespace_padding_in_command_line.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_whitespace_padding_in_command_line.json index fc9b480023c95..f022f0c27ff5e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_whitespace_padding_in_command_line.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_whitespace_padding_in_command_line.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Whitespace Padding in Process Command Line", - "note": "## Triage and analysis\n\n- Analyze the command line of the process in question for evidence of malicious code execution.\n- Review the ancestry and child processes spawned by the process in question for indicators of further malicious code execution.", + "note": "## Triage and analysis\n\n- Analyze the command line of the process in question for evidence of malicious code execution.\n- Review the ancestor and child processes spawned by the process in question for indicators of further malicious code execution.", "query": "process where event.type in (\"start\", \"process_started\") and\n process.command_line regex \".*[ ]{20,}.*\" or \n \n /* this will match on 3 or more separate occurrences of 5+ contiguous whitespace characters */\n process.command_line regex \".*(.*[ ]{5,}[^ ]*){3,}.*\"\n", "references": [ "https://twitter.com/JohnLaTwC/status/1419251082736201737" @@ -40,5 +40,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json index 97ba7da6c5f3b..9af3832303666 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "AdFind Command Activity", - "note": "## Triage and analysis\n\n`AdFind.exe` is a legitimate domain query tool. Rule alerts should be investigated to identify if the user has a role that would explain using this tool and that it is being run from an expected directory and endpoint. Leverage the exception workflow in the Kibana Security App or Elasticsearch API to tune this rule to your environment.", + "note": "## Triage and analysis\n\n### Investigating AdFind Command Activity\n\n[AdFind](http://www.joeware.net/freetools/tools/adfind/) is a freely available command-line tool used to retrieve information from\nActivity Directory (AD). Network discovery and enumeration tools like `AdFind` are useful to adversaries in the same ways\nthey are effective for network administrators. This tool provides quick ability to scope AD person/computer objects and\nunderstand subnets and domain information. There are many [examples](https://thedfirreport.com/category/adfind/)\nobserved where this tool has been adopted by ransomware and criminal groups and used in compromises.\n\n#### Possible investigation steps:\n- `AdFind` is a legitimate Active Directory enumeration tool used by network administrators, it's important to understand\nthe source of the activity. This could involve identifying the account using `AdFind` and determining based on the command-lines\nwhat information was retrieved, then further determining if these actions are in scope of that user's traditional responsibilities.\n- In multiple public references, `AdFind` is leveraged after initial access is achieved, review previous activity on impacted\nmachine looking for suspicious indicators such as previous anti-virus/EDR alerts, phishing emails received, or network traffic\nto suspicious infrastructure\n\n### False Positive Analysis\n- This rule has the high chance to produce false positives as it is a legitimate tool used by network administrators. One\noption could be whitelisting specific users or groups who use the tool as part of their daily responsibilities. This can\nbe done by leveraging the exception workflow in the Kibana Security App or Elasticsearch API to tune this rule to your environment\n- Malicious behavior with `AdFind` should be investigated as part of a step within an attack chain. It doesn't happen in\nisolation, so reviewing previous logs/activity from impacted machines could be very telling.\n\n### Related Rules\n- Windows Network Enumeration\n- Enumeration of Administrator Accounts\n- Enumeration Command Spawned via WMIPrvSE\n\n### Response and Remediation\n- Immediate response should be taken to validate activity, investigate and potentially isolate activity to prevent further\npost-compromise behavior\n- It's important to understand that `AdFind` is an Active Directory enumeration tool and can be used for malicious or legitimate\npurposes, so understanding the intent behind the activity will help determine the appropropriate response.\n", "query": "process where event.type in (\"start\", \"process_started\") and \n (process.name : \"AdFind.exe\" or process.pe.original_file_name == \"AdFind.exe\") and \n process.args : (\"objectcategory=computer\", \"(objectcategory=computer)\", \n \"objectcategory=person\", \"(objectcategory=person)\",\n \"objectcategory=subnet\", \"(objectcategory=subnet)\",\n \"objectcategory=group\", \"(objectcategory=group)\", \n \"objectcategory=organizationalunit\", \"(objectcategory=organizationalunit)\",\n \"objectcategory=attributeschema\", \"(objectcategory=attributeschema)\",\n \"domainlist\", \"dcmodes\", \"adinfo\", \"dclist\", \"computers_pwnotreqd\", \"trustdmp\")\n", "references": [ "http://www.joeware.net/freetools/tools/adfind/", @@ -69,11 +69,16 @@ "id": "T1482", "name": "Domain Trust Discovery", "reference": "https://attack.mitre.org/techniques/T1482/" + }, + { + "id": "T1018", + "name": "Remote System Discovery", + "reference": "https://attack.mitre.org/techniques/T1018/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json index 1a3ceebe7218f..d5026780fdf56 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json @@ -35,7 +35,14 @@ { "id": "T1069", "name": "Permission Groups Discovery", - "reference": "https://attack.mitre.org/techniques/T1069/" + "reference": "https://attack.mitre.org/techniques/T1069/", + "subtechnique": [ + { + "id": "T1069.002", + "name": "Domain Groups", + "reference": "https://attack.mitre.org/techniques/T1069/002/" + } + ] }, { "id": "T1087", @@ -47,5 +54,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json index 87b32d14791bb..dc855f3ed9a57 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json @@ -33,14 +33,14 @@ }, "technique": [ { - "id": "T1087", - "name": "Account Discovery", - "reference": "https://attack.mitre.org/techniques/T1087/" + "id": "T1033", + "name": "System Owner/User Discovery", + "reference": "https://attack.mitre.org/techniques/T1033/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 7 + "version": 8 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json index d0f26c6e41756..92731ab40e78a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json @@ -35,12 +35,19 @@ { "id": "T1518", "name": "Software Discovery", - "reference": "https://attack.mitre.org/techniques/T1518/" + "reference": "https://attack.mitre.org/techniques/T1518/", + "subtechnique": [ + { + "id": "T1518.001", + "name": "Security Software Discovery", + "reference": "https://attack.mitre.org/techniques/T1518/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json new file mode 100644 index 0000000000000..e557e37db23d6 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json @@ -0,0 +1,52 @@ +{ + "author": [ + "Elastic" + ], + "description": "An adversary may attempt to get detailed information about the operating system and hardware. This rule identifies common locations used to discover virtual machine hardware by a non-root user. This technique has been used by the Pupy RAT and other malware.", + "false_positives": [ + "Certain tools or automated software may enumerate hardware information. These tools can be exempted via user name or process arguments to eliminate potential noise." + ], + "from": "now-9m", + "index": [ + "auditbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Virtual Machine Fingerprinting via Grep", + "query": "process where event.type == \"start\" and\n process.name in (\"grep\", \"egrep\") and user.id != \"0\" and\n process.args : (\"parallels*\", \"vmware*\", \"virtualbox*\") and process.args : \"Manufacturer*\" and \n not process.parent.executable in (\"/Applications/Docker.app/Contents/MacOS/Docker\", \"/usr/libexec/kcare/virt-what\")\n", + "references": [ + "https://objective-see.com/blog/blog_0x4F.html" + ], + "risk_score": 47, + "rule_id": "c85eb82c-d2c8-485c-a36f-534f914b7663", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "macOS", + "Linux", + "Threat Detection", + "Discovery" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0007", + "name": "Discovery", + "reference": "https://attack.mitre.org/tactics/TA0007/" + }, + "technique": [ + { + "id": "T1082", + "name": "System Information Discovery", + "reference": "https://attack.mitre.org/techniques/T1082/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_enumeration_via_wmiprvse.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_enumeration_via_wmiprvse.json index 6a967d9644c47..441e01b4a1b12 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_enumeration_via_wmiprvse.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_enumeration_via_wmiprvse.json @@ -38,9 +38,34 @@ "reference": "https://attack.mitre.org/techniques/T1047/" } ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0007", + "name": "Discovery", + "reference": "https://attack.mitre.org/tactics/TA0007/" + }, + "technique": [ + { + "id": "T1518", + "name": "Software Discovery", + "reference": "https://attack.mitre.org/techniques/T1518/" + }, + { + "id": "T1087", + "name": "Account Discovery", + "reference": "https://attack.mitre.org/techniques/T1087/" + }, + { + "id": "T1018", + "name": "Remote System Discovery", + "reference": "https://attack.mitre.org/techniques/T1018/" + } + ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json index abc41d9f6d5c3..094b87f33ada7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json @@ -34,7 +34,20 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [] + "technique": [ + { + "id": "T1204", + "name": "User Execution", + "reference": "https://attack.mitre.org/techniques/T1204/", + "subtechnique": [ + { + "id": "T1204.002", + "name": "Malicious File", + "reference": "https://attack.mitre.org/techniques/T1204/002/" + } + ] + } + ] }, { "framework": "MITRE ATT&CK", @@ -60,5 +73,5 @@ } ], "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json index 24492343e98c0..3814b00321417 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json @@ -41,11 +41,18 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json index efc3884b417fb..73c796c4e206d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json @@ -34,7 +34,20 @@ "name": "Execution", "reference": "https://attack.mitre.org/tactics/TA0002/" }, - "technique": [] + "technique": [ + { + "id": "T1204", + "name": "User Execution", + "reference": "https://attack.mitre.org/techniques/T1204/", + "subtechnique": [ + { + "id": "T1204.002", + "name": "Malicious File", + "reference": "https://attack.mitre.org/techniques/T1204/002/" + } + ] + } + ] }, { "framework": "MITRE ATT&CK", @@ -61,5 +74,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_export.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_export.json index 430d97690b6f4..b59adc45b4236 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_export.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_export.json @@ -1,6 +1,7 @@ { "author": [ - "Elastic" + "Elastic", + "Austin Songer" ], "description": "Identifies the export of an Amazon Relational Database Service (RDS) Aurora database snapshot.", "false_positives": [ @@ -44,5 +45,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json new file mode 100644 index 0000000000000..93c4c287d12ce --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json @@ -0,0 +1,52 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies the deletion of backup files, saved using third-party software, by a process outside of the backup suite. Adversaries may delete Backup files to ensure that recovery from a Ransomware attack is less likely.", + "false_positives": [ + "Certain utilities that delete files for disk cleanup or Administrators manually removing backup files." + ], + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-endpoint.events.*", + "logs-windows.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Third-party Backup Files Deleted via Unexpected Process", + "query": "file where event.type == \"deletion\" and\n (\n /* Veeam Related Backup Files */\n (file.extension : (\"VBK\", \"VIB\", \"VBM\") and\n not process.executable : (\"?:\\\\Windows\\\\Veeam\\\\Backup\\\\*\",\n \"?:\\\\Program Files\\\\Veeam\\\\Backup and Replication\\\\*\",\n \"?:\\\\Program Files (x86)\\\\Veeam\\\\Backup and Replication\\\\*\")) or\n\n /* Veritas Backup Exec Related Backup File */\n (file.extension : \"BKF\" and\n not process.executable : (\"?:\\\\Program Files\\\\Veritas\\\\Backup Exec\\\\*\",\n \"?:\\\\Program Files (x86)\\\\Veritas\\\\Backup Exec\\\\*\"))\n )\n", + "references": [ + "https://www.advintel.io/post/backup-removal-solutions-from-conti-ransomware-with-love" + ], + "risk_score": 47, + "rule_id": "11ea6bec-ebde-4d71-a8e9-784948f8e3e9", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Impact" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" + }, + "technique": [ + { + "id": "T1490", + "name": "Inhibit System Recovery", + "reference": "https://attack.mitre.org/techniques/T1490/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json similarity index 66% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json index 5d1233ebfcb78..0c0c2a71b8263 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json @@ -21,33 +21,26 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Impact" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" }, "technique": [ { - "id": "T1070", - "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/", - "subtechnique": [ - { - "id": "T1070.004", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1070/004/" - } - ] + "id": "T1490", + "name": "Inhibit System Recovery", + "reference": "https://attack.mitre.org/techniques/T1490/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 9 + "version": 10 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json new file mode 100644 index 0000000000000..52094400232b6 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json @@ -0,0 +1,54 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies when Microsoft Cloud App Security reported when a user uploads files to the cloud that might be infected with ransomware.", + "false_positives": [ + "If Cloud App Security identifies, for example, a high rate of file uploads or file deletion activities it may represent an adverse encryption process." + ], + "from": "now-30m", + "index": [ + "filebeat-*", + "logs-o365*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "Microsoft 365 Potential ransomware activity", + "note": "## Config\n\nThe Microsoft 365 Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n", + "query": "event.dataset:o365.audit and event.provider:SecurityComplianceCenter and event.category:web and event.action:\"Potential ransomware activity\" and event.outcome:success\n", + "references": [ + "https://docs.microsoft.com/en-us/cloud-app-security/anomaly-detection-policy", + "https://docs.microsoft.com/en-us/cloud-app-security/policy-template-reference" + ], + "risk_score": 47, + "rule_id": "721999d0-7ab2-44bf-b328-6e63367b9b29", + "severity": "medium", + "tags": [ + "Elastic", + "Cloud", + "Microsoft 365", + "Continuous Monitoring", + "SecOps", + "Configuration Audit" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" + }, + "technique": [ + { + "id": "T1486", + "name": "Data Encrypted for Impact", + "reference": "https://attack.mitre.org/techniques/T1486/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json new file mode 100644 index 0000000000000..c3a53310781df --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json @@ -0,0 +1,54 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies that a user has deleted an unusually large volume of files as reported by Microsoft Cloud App Security.", + "false_positives": [ + "Users or System Administrator cleaning out folders." + ], + "from": "now-30m", + "index": [ + "filebeat-*", + "logs-o365*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "Microsoft 365 Unusual Volume of File Deletion", + "note": "## Config\n\nThe Microsoft 365 Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n", + "query": "event.dataset:o365.audit and event.provider:SecurityComplianceCenter and event.category:web and event.action:\"Unusual volume of file deletion\" and event.outcome:success\n", + "references": [ + "https://docs.microsoft.com/en-us/cloud-app-security/anomaly-detection-policy", + "https://docs.microsoft.com/en-us/cloud-app-security/policy-template-reference" + ], + "risk_score": 47, + "rule_id": "b2951150-658f-4a60-832f-a00d1e6c6745", + "severity": "medium", + "tags": [ + "Elastic", + "Cloud", + "Microsoft 365", + "Continuous Monitoring", + "SecOps", + "Configuration Audit" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" + }, + "technique": [ + { + "id": "T1485", + "name": "Data Destruction", + "reference": "https://attack.mitre.org/techniques/T1485/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json similarity index 69% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json index 7c58d82ec1061..91f5959bee119 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json @@ -21,33 +21,26 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Impact" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" }, "technique": [ { - "id": "T1070", - "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/", - "subtechnique": [ - { - "id": "T1070.004", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1070/004/" - } - ] + "id": "T1490", + "name": "Inhibit System Recovery", + "reference": "https://attack.mitre.org/techniques/T1490/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json similarity index 64% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json index 86903058b62fe..ec361a8795538 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_stop_process_service_threshold.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "This rule identifies a high number (10) of process terminations (stop, delete, or suspend) from the same host within a short time period. This may indicate a defense evasion attempt.", + "description": "This rule identifies a high number (10) of process terminations (stop, delete, or suspend) from the same host within a short time period.", "from": "now-9m", "index": [ "winlogbeat-*", @@ -21,28 +21,21 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Impact" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" }, "technique": [ { - "id": "T1562", - "name": "Impair Defenses", - "reference": "https://attack.mitre.org/techniques/T1562/", - "subtechnique": [ - { - "id": "T1562.001", - "name": "Disable or Modify Tools", - "reference": "https://attack.mitre.org/techniques/T1562/001/" - } - ] + "id": "T1489", + "name": "Service Stop", + "reference": "https://attack.mitre.org/techniques/T1489/" } ] } @@ -54,5 +47,5 @@ "value": 10 }, "type": "threshold", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json similarity index 70% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json index f0ac38e98441e..940229bf63751 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "Identifies use of vssadmin.exe for shadow copy deletion on endpoints. This commonly occurs in tandem with ransomware or other destructive attacks.", + "description": "Identifies use of vssadmin.exe for shadow copy deletion or resizing on endpoints. This commonly occurs in tandem with ransomware or other destructive attacks.", "from": "now-9m", "index": [ "winlogbeat-*", @@ -11,8 +11,8 @@ ], "language": "eql", "license": "Elastic License v2", - "name": "Volume Shadow Copy Deletion via VssAdmin", - "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"vssadmin.exe\" or process.pe.original_file_name == \"VSSADMIN.EXE\") and\n process.args : \"delete\" and process.args : \"shadows\"\n", + "name": "Volume Shadow Copy Deleted or Resized via VssAdmin", + "query": "process where event.type in (\"start\", \"process_started\") and event.action == \"start\" \n and (process.name : \"vssadmin.exe\" or process.pe.original_file_name == \"VSSADMIN.EXE\") and\n process.args in (\"delete\", \"resize\") and process.args : \"shadows*\"\n", "risk_score": 73, "rule_id": "b5ea4bfe-a1b2-421f-9d47-22a75a6f2921", "severity": "high", @@ -42,5 +42,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 9 + "version": 10 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json new file mode 100644 index 0000000000000..43dce4acf4df8 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json @@ -0,0 +1,52 @@ +{ + "author": [ + "Elastic", + "Austin Songer" + ], + "description": "Identifies the use of the Win32_ShadowCopy class and related cmdlets to achieve shadow copy deletion. This commonly occurs in tandem with ransomware or other destructive attacks.", + "from": "now-9m", + "index": [ + "winlogbeat-*", + "logs-endpoint.events.*", + "logs-windows.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Volume Shadow Copy Deletion via PowerShell", + "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : (\"powershell.exe\", \"pwsh.exe\") and \n process.args : (\"*Get-WmiObject*\", \"*gwmi*\", \"*Get-CimInstance*\", \"*gcim*\") and\n process.args : (\"*Win32_ShadowCopy*\") and\n process.args : (\"*.Delete()*\", \"*Remove-WmiObject*\", \"*rwmi*\", \"*Remove-CimInstance*\", \"*rcim*\")\n", + "references": [ + "https://docs.microsoft.com/en-us/previous-versions/windows/desktop/vsswmi/win32-shadowcopy", + "https://powershell.one/wmi/root/cimv2/win32_shadowcopy", + "https://www.fortinet.com/blog/threat-research/stomping-shadow-copies-a-second-look-into-deletion-methods" + ], + "risk_score": 73, + "rule_id": "d99a037b-c8e2-47a5-97b9-170d076827c4", + "severity": "high", + "tags": [ + "Elastic", + "Host", + "Windows", + "Threat Detection", + "Impact" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" + }, + "technique": [ + { + "id": "T1490", + "name": "Inhibit System Recovery", + "reference": "https://attack.mitre.org/techniques/T1490/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json similarity index 66% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json index e519b23a32b0d..f4f530362a5b8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json @@ -21,33 +21,26 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Impact" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0005", - "name": "Defense Evasion", - "reference": "https://attack.mitre.org/tactics/TA0005/" + "id": "TA0040", + "name": "Impact", + "reference": "https://attack.mitre.org/tactics/TA0040/" }, "technique": [ { - "id": "T1070", - "name": "Indicator Removal on Host", - "reference": "https://attack.mitre.org/techniques/T1070/", - "subtechnique": [ - { - "id": "T1070.004", - "name": "File Deletion", - "reference": "https://attack.mitre.org/techniques/T1070/004/" - } - ] + "id": "T1490", + "name": "Inhibit System Recovery", + "reference": "https://attack.mitre.org/techniques/T1490/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 9 + "version": 10 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts index 093d5c806c282..1c5006f5e6f48 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts @@ -41,38 +41,38 @@ import rule28 from './command_and_control_vnc_virtual_network_computing_to_the_i import rule29 from './defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json'; import rule30 from './defense_evasion_clearing_windows_event_logs.json'; import rule31 from './defense_evasion_delete_volume_usn_journal_with_fsutil.json'; -import rule32 from './defense_evasion_deleting_backup_catalogs_with_wbadmin.json'; -import rule33 from './defense_evasion_disable_windows_firewall_rules_with_netsh.json'; -import rule34 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json'; -import rule35 from './defense_evasion_msbuild_making_network_connections.json'; -import rule36 from './defense_evasion_suspicious_certutil_commands.json'; -import rule37 from './defense_evasion_unusual_network_connection_via_rundll32.json'; -import rule38 from './defense_evasion_unusual_process_network_connection.json'; -import rule39 from './defense_evasion_via_filter_manager.json'; -import rule40 from './defense_evasion_volume_shadow_copy_deletion_via_wmic.json'; -import rule41 from './discovery_whoami_command_activity.json'; -import rule42 from './endgame_adversary_behavior_detected.json'; -import rule43 from './endgame_cred_dumping_detected.json'; -import rule44 from './endgame_cred_dumping_prevented.json'; -import rule45 from './endgame_cred_manipulation_detected.json'; -import rule46 from './endgame_cred_manipulation_prevented.json'; -import rule47 from './endgame_exploit_detected.json'; -import rule48 from './endgame_exploit_prevented.json'; -import rule49 from './endgame_malware_detected.json'; -import rule50 from './endgame_malware_prevented.json'; -import rule51 from './endgame_permission_theft_detected.json'; -import rule52 from './endgame_permission_theft_prevented.json'; -import rule53 from './endgame_process_injection_detected.json'; -import rule54 from './endgame_process_injection_prevented.json'; -import rule55 from './endgame_ransomware_detected.json'; -import rule56 from './endgame_ransomware_prevented.json'; -import rule57 from './execution_command_prompt_connecting_to_the_internet.json'; -import rule58 from './execution_command_shell_started_by_svchost.json'; -import rule59 from './execution_html_help_executable_program_connecting_to_the_internet.json'; -import rule60 from './execution_psexec_lateral_movement_command.json'; -import rule61 from './execution_register_server_program_connecting_to_the_internet.json'; -import rule62 from './execution_via_compiled_html_file.json'; -import rule63 from './impact_volume_shadow_copy_deletion_via_vssadmin.json'; +import rule32 from './defense_evasion_disable_windows_firewall_rules_with_netsh.json'; +import rule33 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json'; +import rule34 from './defense_evasion_msbuild_making_network_connections.json'; +import rule35 from './defense_evasion_suspicious_certutil_commands.json'; +import rule36 from './defense_evasion_unusual_network_connection_via_rundll32.json'; +import rule37 from './defense_evasion_unusual_process_network_connection.json'; +import rule38 from './defense_evasion_via_filter_manager.json'; +import rule39 from './discovery_whoami_command_activity.json'; +import rule40 from './endgame_adversary_behavior_detected.json'; +import rule41 from './endgame_cred_dumping_detected.json'; +import rule42 from './endgame_cred_dumping_prevented.json'; +import rule43 from './endgame_cred_manipulation_detected.json'; +import rule44 from './endgame_cred_manipulation_prevented.json'; +import rule45 from './endgame_exploit_detected.json'; +import rule46 from './endgame_exploit_prevented.json'; +import rule47 from './endgame_malware_detected.json'; +import rule48 from './endgame_malware_prevented.json'; +import rule49 from './endgame_permission_theft_detected.json'; +import rule50 from './endgame_permission_theft_prevented.json'; +import rule51 from './endgame_process_injection_detected.json'; +import rule52 from './endgame_process_injection_prevented.json'; +import rule53 from './endgame_ransomware_detected.json'; +import rule54 from './endgame_ransomware_prevented.json'; +import rule55 from './execution_command_prompt_connecting_to_the_internet.json'; +import rule56 from './execution_command_shell_started_by_svchost.json'; +import rule57 from './execution_html_help_executable_program_connecting_to_the_internet.json'; +import rule58 from './execution_psexec_lateral_movement_command.json'; +import rule59 from './execution_register_server_program_connecting_to_the_internet.json'; +import rule60 from './execution_via_compiled_html_file.json'; +import rule61 from './impact_deleting_backup_catalogs_with_wbadmin.json'; +import rule62 from './impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json'; +import rule63 from './impact_volume_shadow_copy_deletion_via_wmic.json'; import rule64 from './initial_access_rpc_remote_procedure_call_from_the_internet.json'; import rule65 from './initial_access_rpc_remote_procedure_call_to_the_internet.json'; import rule66 from './initial_access_script_executing_powershell.json'; @@ -95,7 +95,7 @@ import rule82 from './persistence_system_shells_via_services.json'; import rule83 from './persistence_user_account_creation.json'; import rule84 from './persistence_via_application_shimming.json'; import rule85 from './privilege_escalation_unusual_parentchild_relationship.json'; -import rule86 from './defense_evasion_modification_of_boot_config.json'; +import rule86 from './impact_modification_of_boot_config.json'; import rule87 from './privilege_escalation_uac_bypass_event_viewer.json'; import rule88 from './defense_evasion_msxsl_network.json'; import rule89 from './discovery_net_command_system_account.json'; @@ -328,7 +328,7 @@ import rule315 from './command_and_control_cobalt_strike_default_teamserver_cert import rule316 from './defense_evasion_enable_inbound_rdp_with_netsh.json'; import rule317 from './defense_evasion_execution_lolbas_wuauclt.json'; import rule318 from './privilege_escalation_unusual_svchost_childproc_childless.json'; -import rule319 from './lateral_movement_rdp_tunnel_plink.json'; +import rule319 from './command_and_control_rdp_tunnel_plink.json'; import rule320 from './privilege_escalation_uac_bypass_winfw_mmc_hijack.json'; import rule321 from './persistence_ms_office_addins_file.json'; import rule322 from './discovery_adfind_command_activity.json'; @@ -428,8 +428,8 @@ import rule415 from './credential_access_copy_ntds_sam_volshadowcp_cmdline.json' import rule416 from './credential_access_lsass_memdump_file_created.json'; import rule417 from './lateral_movement_incoming_winrm_shell_execution.json'; import rule418 from './lateral_movement_powershell_remoting_target.json'; -import rule419 from './defense_evasion_hide_encoded_executable_registry.json'; -import rule420 from './defense_evasion_port_forwarding_added_registry.json'; +import rule419 from './command_and_control_port_forwarding_added_registry.json'; +import rule420 from './defense_evasion_hide_encoded_executable_registry.json'; import rule421 from './lateral_movement_rdp_enabled_registry.json'; import rule422 from './privilege_escalation_printspooler_registry_copyfiles.json'; import rule423 from './privilege_escalation_rogue_windir_environment_var.json'; @@ -443,7 +443,7 @@ import rule430 from './credential_access_microsoft_365_brute_force_user_account_ import rule431 from './microsoft_365_teams_custom_app_interaction_allowed.json'; import rule432 from './persistence_microsoft_365_teams_external_access_enabled.json'; import rule433 from './credential_access_microsoft_365_potential_password_spraying_attack.json'; -import rule434 from './defense_evasion_stop_process_service_threshold.json'; +import rule434 from './impact_stop_process_service_threshold.json'; import rule435 from './collection_winrar_encryption.json'; import rule436 from './defense_evasion_unusual_dir_ads.json'; import rule437 from './discovery_admin_recon.json'; @@ -466,8 +466,8 @@ import rule453 from './execution_apt_solarwinds_backdoor_child_cmd_powershell.js import rule454 from './execution_apt_solarwinds_backdoor_unusual_child_processes.json'; import rule455 from './initial_access_azure_active_directory_powershell_signin.json'; import rule456 from './collection_email_powershell_exchange_mailbox.json'; -import rule457 from './collection_persistence_powershell_exch_mailbox_activesync_add_device.json'; -import rule458 from './execution_scheduled_task_powershell_source.json'; +import rule457 from './execution_scheduled_task_powershell_source.json'; +import rule458 from './persistence_powershell_exch_mailbox_activesync_add_device.json'; import rule459 from './persistence_docker_shortcuts_plist_modification.json'; import rule460 from './persistence_evasion_hidden_local_account_creation.json'; import rule461 from './persistence_finder_sync_plugin_pluginkit.json'; @@ -551,36 +551,54 @@ import rule538 from './persistence_ec2_security_group_configuration_change_detec import rule539 from './defense_evasion_disabling_windows_logs.json'; import rule540 from './persistence_route_53_domain_transfer_lock_disabled.json'; import rule541 from './persistence_route_53_domain_transferred_to_another_account.json'; -import rule542 from './credential_access_user_excessive_sso_logon_errors.json'; -import rule543 from './defense_evasion_suspicious_execution_from_mounted_device.json'; -import rule544 from './defense_evasion_unusual_network_connection_via_dllhost.json'; -import rule545 from './defense_evasion_amsienable_key_mod.json'; -import rule546 from './impact_rds_group_deletion.json'; -import rule547 from './persistence_rds_group_creation.json'; -import rule548 from './exfiltration_rds_snapshot_export.json'; -import rule549 from './persistence_rds_instance_creation.json'; -import rule550 from './ml_auth_rare_hour_for_a_user_to_logon.json'; -import rule551 from './ml_auth_rare_source_ip_for_a_user.json'; -import rule552 from './ml_auth_rare_user_logon.json'; -import rule553 from './ml_auth_spike_in_failed_logon_events.json'; -import rule554 from './ml_auth_spike_in_logon_events.json'; -import rule555 from './ml_auth_spike_in_logon_events_from_a_source_ip.json'; -import rule556 from './privilege_escalation_cyberarkpas_error_audit_event_promotion.json'; -import rule557 from './privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json'; -import rule558 from './privilege_escalation_printspooler_malicious_driver_file_changes.json'; -import rule559 from './privilege_escalation_printspooler_malicious_registry_modification.json'; -import rule560 from './privilege_escalation_printspooler_suspicious_file_deletion.json'; -import rule561 from './privilege_escalation_unusual_printspooler_childprocess.json'; -import rule562 from './defense_evasion_disabling_windows_defender_powershell.json'; -import rule563 from './defense_evasion_enable_network_discovery_with_netsh.json'; -import rule564 from './defense_evasion_execution_windefend_unusual_path.json'; -import rule565 from './defense_evasion_agent_spoofing_mismatched_id.json'; -import rule566 from './defense_evasion_agent_spoofing_multiple_hosts.json'; -import rule567 from './defense_evasion_parent_process_pid_spoofing.json'; -import rule568 from './defense_evasion_defender_exclusion_via_powershell.json'; -import rule569 from './defense_evasion_whitespace_padding_in_command_line.json'; -import rule570 from './persistence_webshell_detection.json'; -import rule571 from './persistence_via_bits_job_notify_command.json'; +import rule542 from './initial_access_okta_user_attempted_unauthorized_access.json'; +import rule543 from './credential_access_user_excessive_sso_logon_errors.json'; +import rule544 from './persistence_exchange_suspicious_mailbox_right_delegation.json'; +import rule545 from './privilege_escalation_new_or_modified_federation_domain.json'; +import rule546 from './privilege_escalation_sts_getsessiontoken_abuse.json'; +import rule547 from './defense_evasion_suspicious_execution_from_mounted_device.json'; +import rule548 from './defense_evasion_unusual_network_connection_via_dllhost.json'; +import rule549 from './defense_evasion_amsienable_key_mod.json'; +import rule550 from './impact_rds_group_deletion.json'; +import rule551 from './persistence_rds_group_creation.json'; +import rule552 from './persistence_route_table_modified_or_deleted.json'; +import rule553 from './exfiltration_rds_snapshot_export.json'; +import rule554 from './persistence_rds_instance_creation.json'; +import rule555 from './ml_auth_rare_hour_for_a_user_to_logon.json'; +import rule556 from './ml_auth_rare_source_ip_for_a_user.json'; +import rule557 from './ml_auth_rare_user_logon.json'; +import rule558 from './ml_auth_spike_in_failed_logon_events.json'; +import rule559 from './ml_auth_spike_in_logon_events.json'; +import rule560 from './ml_auth_spike_in_logon_events_from_a_source_ip.json'; +import rule561 from './privilege_escalation_cyberarkpas_error_audit_event_promotion.json'; +import rule562 from './privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json'; +import rule563 from './privilege_escalation_printspooler_malicious_driver_file_changes.json'; +import rule564 from './privilege_escalation_printspooler_malicious_registry_modification.json'; +import rule565 from './privilege_escalation_printspooler_suspicious_file_deletion.json'; +import rule566 from './privilege_escalation_unusual_printspooler_childprocess.json'; +import rule567 from './defense_evasion_disabling_windows_defender_powershell.json'; +import rule568 from './defense_evasion_enable_network_discovery_with_netsh.json'; +import rule569 from './defense_evasion_execution_windefend_unusual_path.json'; +import rule570 from './defense_evasion_agent_spoofing_mismatched_id.json'; +import rule571 from './defense_evasion_agent_spoofing_multiple_hosts.json'; +import rule572 from './defense_evasion_parent_process_pid_spoofing.json'; +import rule573 from './impact_microsoft_365_potential_ransomware_activity.json'; +import rule574 from './impact_microsoft_365_unusual_volume_of_file_deletion.json'; +import rule575 from './initial_access_microsoft_365_user_restricted_from_sending_email.json'; +import rule576 from './defense_evasion_elasticache_security_group_creation.json'; +import rule577 from './defense_evasion_elasticache_security_group_modified_or_deleted.json'; +import rule578 from './impact_volume_shadow_copy_deletion_via_powershell.json'; +import rule579 from './defense_evasion_defender_exclusion_via_powershell.json'; +import rule580 from './defense_evasion_whitespace_padding_in_command_line.json'; +import rule581 from './defense_evasion_frontdoor_firewall_policy_deletion.json'; +import rule582 from './persistence_webshell_detection.json'; +import rule583 from './defense_evasion_execution_control_panel_suspicious_args.json'; +import rule584 from './credential_access_potential_lsa_memdump_via_mirrordump.json'; +import rule585 from './discovery_virtual_machine_fingerprinting_grep.json'; +import rule586 from './impact_backup_file_deletion.json'; +import rule587 from './persistence_screensaver_engine_unexpected_child_process.json'; +import rule588 from './persistence_screensaver_plist_file_modification.json'; +import rule589 from './persistence_via_bits_job_notify_command.json'; export const rawRules = [ rule1, @@ -1154,4 +1172,22 @@ export const rawRules = [ rule569, rule570, rule571, + rule572, + rule573, + rule574, + rule575, + rule576, + rule577, + rule578, + rule579, + rule580, + rule581, + rule582, + rule583, + rule584, + rule585, + rule586, + rule587, + rule588, + rule589, ]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json new file mode 100644 index 0000000000000..31950fc345c0e --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json @@ -0,0 +1,54 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies when a user has been restricted from sending email due to exceeding sending limits of the service policies per the Security Compliance Center.", + "false_positives": [ + "A user sending emails using personal distribution folders may trigger the event." + ], + "from": "now-30m", + "index": [ + "filebeat-*", + "logs-o365*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "Microsoft 365 User Restricted from Sending Email", + "note": "## Config\n\nThe Microsoft 365 Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n", + "query": "event.dataset:o365.audit and event.provider:SecurityComplianceCenter and event.category:web and event.action:\"User restricted from sending email\" and event.outcome:success\n", + "references": [ + "https://docs.microsoft.com/en-us/cloud-app-security/anomaly-detection-policy", + "https://docs.microsoft.com/en-us/cloud-app-security/policy-template-reference" + ], + "risk_score": 47, + "rule_id": "0136b315-b566-482f-866c-1d8e2477ba16", + "severity": "medium", + "tags": [ + "Elastic", + "Cloud", + "Microsoft 365", + "Continuous Monitoring", + "SecOps", + "Configuration Audit" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1078", + "name": "Valid Accounts", + "reference": "https://attack.mitre.org/techniques/T1078/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json new file mode 100644 index 0000000000000..222d30723bc9e --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json @@ -0,0 +1,74 @@ +{ + "author": [ + "Elastic", + "Austin Songer" + ], + "description": "Identifies when an unauthorized access attempt is made by a user for an Okta application.", + "index": [ + "filebeat-*", + "logs-okta*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "Unauthorized Access to an Okta Application", + "note": "## Config\n\nThe Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:okta.system and event.action:app.generic.unauth_app_access_attempt\n", + "risk_score": 21, + "rule_id": "4edd3e1a-3aa0-499b-8147-4d2ea43b1613", + "severity": "low", + "tags": [ + "Elastic", + "Identity", + "Okta", + "Continuous Monitoring", + "SecOps", + "Identity and Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0001", + "name": "Initial Access", + "reference": "https://attack.mitre.org/tactics/TA0001/" + }, + "technique": [ + { + "id": "T1078", + "name": "Valid Accounts", + "reference": "https://attack.mitre.org/techniques/T1078/" + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" + }, + "technique": [] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0004", + "name": "Privilege Escalation", + "reference": "https://attack.mitre.org/tactics/TA0004/" + }, + "technique": [] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json index 16486590cb093..17e9195181f3d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious MS Office Child Process", - "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : (\"eqnedt32.exe\", \"excel.exe\", \"fltldr.exe\", \"msaccess.exe\", \"mspub.exe\", \"powerpnt.exe\", \"winword.exe\") and\n process.name : (\"Microsoft.Workflow.Compiler.exe\", \"arp.exe\", \"atbroker.exe\", \"bginfo.exe\", \"bitsadmin.exe\", \"cdb.exe\", \"certutil.exe\",\n \"cmd.exe\", \"cmstp.exe\", \"cscript.exe\", \"csi.exe\", \"dnx.exe\", \"dsget.exe\", \"dsquery.exe\", \"forfiles.exe\", \"fsi.exe\",\n \"ftp.exe\", \"gpresult.exe\", \"hostname.exe\", \"ieexec.exe\", \"iexpress.exe\", \"installutil.exe\", \"ipconfig.exe\", \"mshta.exe\",\n \"msxsl.exe\", \"nbtstat.exe\", \"net.exe\", \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"odbcconf.exe\", \"ping.exe\",\n \"powershell.exe\", \"pwsh.exe\", \"qprocess.exe\", \"quser.exe\", \"qwinsta.exe\", \"rcsi.exe\", \"reg.exe\", \"regasm.exe\", \"regsvcs.exe\",\n \"regsvr32.exe\", \"sc.exe\", \"schtasks.exe\", \"systeminfo.exe\", \"tasklist.exe\", \"tracert.exe\", \"whoami.exe\",\n \"wmic.exe\", \"wscript.exe\", \"xwizard.exe\", \"explorer.exe\", \"rundll32.exe\", \"hh.exe\")\n", + "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : (\"eqnedt32.exe\", \"excel.exe\", \"fltldr.exe\", \"msaccess.exe\", \"mspub.exe\", \"powerpnt.exe\", \"winword.exe\") and\n process.name : (\"Microsoft.Workflow.Compiler.exe\", \"arp.exe\", \"atbroker.exe\", \"bginfo.exe\", \"bitsadmin.exe\", \"cdb.exe\", \"certutil.exe\",\n \"cmd.exe\", \"cmstp.exe\", \"control.exe\", \"cscript.exe\", \"csi.exe\", \"dnx.exe\", \"dsget.exe\", \"dsquery.exe\", \"forfiles.exe\", \n \"fsi.exe\", \"ftp.exe\", \"gpresult.exe\", \"hostname.exe\", \"ieexec.exe\", \"iexpress.exe\", \"installutil.exe\", \"ipconfig.exe\", \n \"mshta.exe\", \"msxsl.exe\", \"nbtstat.exe\", \"net.exe\", \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"odbcconf.exe\", \n \"ping.exe\", \"powershell.exe\", \"pwsh.exe\", \"qprocess.exe\", \"quser.exe\", \"qwinsta.exe\", \"rcsi.exe\", \"reg.exe\", \"regasm.exe\", \n \"regsvcs.exe\", \"regsvr32.exe\", \"sc.exe\", \"schtasks.exe\", \"systeminfo.exe\", \"tasklist.exe\", \"tracert.exe\", \"whoami.exe\",\n \"wmic.exe\", \"wscript.exe\", \"xwizard.exe\", \"explorer.exe\", \"rundll32.exe\", \"hh.exe\")\n", "risk_score": 47, "rule_id": "a624863f-a70d-417f-a7d2-7a404638d47f", "severity": "medium", @@ -49,5 +49,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json index 82fa9d8d72a92..0fd10fc807846 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json @@ -60,12 +60,19 @@ { "id": "T1558", "name": "Steal or Forge Kerberos Tickets", - "reference": "https://attack.mitre.org/techniques/T1558/" + "reference": "https://attack.mitre.org/techniques/T1558/", + "subtechnique": [ + { + "id": "T1558.003", + "name": "Kerberoasting", + "reference": "https://attack.mitre.org/techniques/T1558/003/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_hta.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_hta.json index 707596aa333d0..f832eb51336f8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_hta.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_hta.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Incoming DCOM Lateral Movement via MSHTA", - "query": "sequence with maxspan=1m\n [process where event.type in (\"start\", \"process_started\") and\n process.name : \"mshta.exe\" and process.args : \"-Embedding\"\n ] by host.id, process.entity_id\n [network where event.type == \"start\" and process.name : \"mshta.exe\" and \n network.direction == \"incoming\" and network.transport == \"tcp\" and\n source.port > 49151 and destination.port > 49151 and not source.address in (\"127.0.0.1\", \"::1\")\n ] by host.id, process.entity_id\n", + "query": "sequence with maxspan=1m\n [process where event.type in (\"start\", \"process_started\") and\n process.name : \"mshta.exe\" and process.args : \"-Embedding\"\n ] by host.id, process.entity_id\n [network where event.type == \"start\" and process.name : \"mshta.exe\" and \n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\" and\n source.port > 49151 and destination.port > 49151 and not source.address in (\"127.0.0.1\", \"::1\")\n ] by host.id, process.entity_id\n", "references": [ "https://codewhitesec.blogspot.com/2018/07/lethalhta.html" ], @@ -38,11 +38,40 @@ { "id": "T1021", "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.003", + "name": "Distributed Component Object Model", + "reference": "https://attack.mitre.org/techniques/T1021/003/" + } + ] + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0005", + "name": "Defense Evasion", + "reference": "https://attack.mitre.org/tactics/TA0005/" + }, + "technique": [ + { + "id": "T1218", + "name": "Signed Binary Proxy Execution", + "reference": "https://attack.mitre.org/techniques/T1218/", + "subtechnique": [ + { + "id": "T1218.005", + "name": "Mshta", + "reference": "https://attack.mitre.org/techniques/T1218/005/" + } + ] } ] } ], "type": "eql", - "version": 2 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_mmc20.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_mmc20.json index c78343223a10f..8cb2e2c3690e6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_mmc20.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_mmc20.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Incoming DCOM Lateral Movement with MMC", - "query": "sequence by host.id with maxspan=1m\n [network where event.type == \"start\" and process.name : \"mmc.exe\" and\n source.port >= 49152 and destination.port >= 49152 and source.address not in (\"127.0.0.1\", \"::1\") and\n network.direction == \"incoming\" and network.transport == \"tcp\"\n ] by process.entity_id\n [process where event.type in (\"start\", \"process_started\") and process.parent.name : \"mmc.exe\"\n ] by process.parent.entity_id\n", + "query": "sequence by host.id with maxspan=1m\n [network where event.type == \"start\" and process.name : \"mmc.exe\" and\n source.port >= 49152 and destination.port >= 49152 and source.address not in (\"127.0.0.1\", \"::1\") and\n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\"\n ] by process.entity_id\n [process where event.type in (\"start\", \"process_started\") and process.parent.name : \"mmc.exe\"\n ] by process.parent.entity_id\n", "references": [ "https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/" ], @@ -38,11 +38,18 @@ { "id": "T1021", "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.003", + "name": "Distributed Component Object Model", + "reference": "https://attack.mitre.org/techniques/T1021/003/" + } + ] } ] } ], "type": "eql", - "version": 2 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json index 617cbc2fab05e..9ca759cc2facd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Incoming DCOM Lateral Movement with ShellBrowserWindow or ShellWindows", - "query": "sequence by host.id with maxspan=5s\n [network where event.type == \"start\" and process.name : \"explorer.exe\" and\n network.direction == \"incoming\" and network.transport == \"tcp\" and\n source.port > 49151 and destination.port > 49151 and not source.address in (\"127.0.0.1\", \"::1\")\n ] by process.entity_id\n [process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"explorer.exe\"\n ] by process.parent.entity_id\n", + "query": "sequence by host.id with maxspan=5s\n [network where event.type == \"start\" and process.name : \"explorer.exe\" and\n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\" and\n source.port > 49151 and destination.port > 49151 and not source.address in (\"127.0.0.1\", \"::1\")\n ] by process.entity_id\n [process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"explorer.exe\"\n ] by process.parent.entity_id\n", "references": [ "https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/" ], @@ -38,11 +38,18 @@ { "id": "T1021", "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.003", + "name": "Distributed Component Object Model", + "reference": "https://attack.mitre.org/techniques/T1021/003/" + } + ] } ] } ], "type": "eql", - "version": 2 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json index b4534c48d0fa2..c9983d2ba186e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json @@ -33,13 +33,20 @@ }, "technique": [ { - "id": "T1210", - "name": "Exploitation of Remote Services", - "reference": "https://attack.mitre.org/techniques/T1210/" + "id": "T1021", + "name": "Remote Services", + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.002", + "name": "SMB/Windows Admin Shares", + "reference": "https://attack.mitre.org/techniques/T1021/002/" + } + ] } ] } ], "type": "eql", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json index b34badc7c8611..6e11258e23d00 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json @@ -13,7 +13,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "Abnormally Large DNS Response", - "note": "## Triage and analysis\n\n### Investigating Large DNS Responses\nDetection alerts from this rule indicate an attempt was made to exploit CVE-2020-1350 (SigRed) through the use of large DNS responses on a Windows DNS server. Here are some possible avenues of investigation:\n- Investigate any corresponding Intrusion Detection Signatures (IDS) alerts that can validate this detection alert.\n- Examine the `dns.question_type` network fieldset with a protocol analyzer, such as Zeek, Packetbeat, or Suricata, for `SIG` or `RRSIG` data.\n- Validate the patch level and OS of the targeted DNS server to validate the observed activity was not large-scale Internet vulnerability scanning.\n- Validate that the source of the network activity was not from an authorized vulnerability scan or compromise assessment.", + "note": "## Triage and analysis\n\n### Investigating Large DNS Responses\nDetection alerts from this rule indicate possible anomalous activity around large byte DNS responses from a Windows DNS\nserver. This detection rule was created based on activity represented in exploitation of vulnerability (CVE-2020-1350)\nalso known as [SigRed](https://www.elastic.co/blog/detection-rules-for-sigred-vulnerability) during July 2020.\n\n#### Possible investigation steps:\n- This specific rule is sourced from network log activity such as DNS or network level data. It's important to validate\nthe source of the incoming traffic and determine if this activity has been observed previously within an environment.\n- Activity can be further investigated and validated by reviewing available corresponding Intrusion Detection Signatures (IDS) alerts associated with activity.\n- Further examination can be made by reviewing the `dns.question_type` network fieldset with a protocol analyzer, such as Zeek, Packetbeat, or Suricata, for `SIG` or `RRSIG` data.\n- Validate the patch level and OS of the targeted DNS server to validate the observed activity was not large-scale Internet vulnerability scanning.\n- Validate that the source of the network activity was not from an authorized vulnerability scan or compromise assessment.\n\n#### False Positive Analysis\n- Based on this rule which looks for a threshold of 60k bytes, it is possible for activity to be generated under 65k bytes\nand related to legitimate behavior. In packet capture files received by the [SANS Internet Storm Center](https://isc.sans.edu/forums/diary/PATCH+NOW+SIGRed+CVE20201350+Microsoft+DNS+Server+Vulnerability/26356/), byte responses\nwere all observed as greater than 65k bytes.\n- This activity has the ability to be triggered from compliance/vulnerability scanning or compromise assessment, it's\nimportant to determine the source of the activity and potential whitelist the source host\n\n\n### Related Rules\n- Unusual Child Process of dns.exe\n- Unusual File Modification by dns.exe\n\n### Response and Remediation\n- Review and implement the above detection logic within your environment using technology such as Endpoint security, Winlogbeat, Packetbeat, or network security monitoring (NSM) platforms such as Zeek or Suricata.\n- Ensure that you have deployed the latest Microsoft [Security Update](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1350) (Monthly Rollup or Security Only) and restart the\npatched machines. If unable to patch immediately: Microsoft [released](https://support.microsoft.com/en-us/help/4569509/windows-dns-server-remote-code-execution-vulnerability) a registry-based workaround that doesn\u2019t require a\nrestart. This can be used as a temporary solution before the patch is applied.\n- Maintain backups of your critical systems to aid in quick recovery.\n- Perform routine vulnerability scans of your systems, monitor [CISA advisories](https://us-cert.cisa.gov/ncas/current-activity) and patch identified vulnerabilities.\n- If observed true positive activity, implement a remediation plan and monitor host-based artifacts for additional post-exploitation behavior.\n", "query": "event.category:(network or network_traffic) and destination.port:53 and\n (event.dataset:zeek.dns or type:dns or event.type:connection) and network.bytes > 60000\n", "references": [ "https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/", @@ -48,5 +48,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json index 8173ddc6f1003..5fe9d066bc76d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Lateral Tool Transfer", - "query": "sequence by host.id with maxspan=30s\n [network where event.type == \"start\" and process.pid == 4 and destination.port == 445 and\n network.direction == \"incoming\" and network.transport == \"tcp\" and\n source.address != \"127.0.0.1\" and source.address != \"::1\"\n ] by process.entity_id\n /* add more executable extensions here if they are not noisy in your environment */\n [file where event.type in (\"creation\", \"change\") and process.pid == 4 and file.extension : (\"exe\", \"dll\", \"bat\", \"cmd\")] by process.entity_id\n", + "query": "sequence by host.id with maxspan=30s\n [network where event.type == \"start\" and process.pid == 4 and destination.port == 445 and\n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\" and\n source.address != \"127.0.0.1\" and source.address != \"::1\"\n ] by process.entity_id\n /* add more executable extensions here if they are not noisy in your environment */\n [file where event.type in (\"creation\", \"change\") and process.pid == 4 and file.extension : (\"exe\", \"dll\", \"bat\", \"cmd\")] by process.entity_id\n", "risk_score": 47, "rule_id": "58bc134c-e8d2-4291-a552-b4b3e537c60b", "severity": "medium", @@ -41,5 +41,5 @@ } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json index 062013549e1da..04a60f99556f4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Incoming Execution via WinRM Remote Shell", - "query": "sequence by host.id with maxspan=30s\n [network where process.pid == 4 and network.direction == \"incoming\" and\n destination.port in (5985, 5986) and network.protocol == \"http\" and not source.address in (\"::1\", \"127.0.0.1\")\n ]\n [process where event.type == \"start\" and process.parent.name : \"winrshost.exe\" and not process.name : \"conhost.exe\"]\n", + "query": "sequence by host.id with maxspan=30s\n [network where process.pid == 4 and network.direction : (\"incoming\", \"ingress\") and\n destination.port in (5985, 5986) and network.protocol == \"http\" and not source.address in (\"::1\", \"127.0.0.1\")\n ]\n [process where event.type == \"start\" and process.parent.name : \"winrshost.exe\" and not process.name : \"conhost.exe\"]\n", "risk_score": 47, "rule_id": "1cd01db9-be24-4bef-8e7c-e923f0ff78ab", "severity": "medium", @@ -44,5 +44,5 @@ } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json index 901a19d896ff3..9b13ade43812f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "WMI Incoming Lateral Movement", - "query": "sequence by host.id with maxspan = 2s\n\n /* Accepted Incoming RPC connection by Winmgmt service */\n\n [network where process.name : \"svchost.exe\" and network.direction == \"incoming\" and\n source.address != \"127.0.0.1\" and source.address != \"::1\" and \n source.port >= 49152 and destination.port >= 49152\n ]\n\n /* Excluding Common FPs Nessus and SCCM */\n\n [process where event.type in (\"start\", \"process_started\") and process.parent.name : \"WmiPrvSE.exe\" and\n not process.args : (\"C:\\\\windows\\\\temp\\\\nessus_*.txt\", \n \"C:\\\\windows\\\\TEMP\\\\nessus_*.TMP\", \n \"C:\\\\Windows\\\\CCM\\\\SystemTemp\\\\*\", \n \"C:\\\\Windows\\\\CCMCache\\\\*\", \n \"C:\\\\CCM\\\\Cache\\\\*\")\n ]\n", + "query": "sequence by host.id with maxspan = 2s\n\n /* Accepted Incoming RPC connection by Winmgmt service */\n\n [network where process.name : \"svchost.exe\" and network.direction : (\"incoming\", \"ingress\") and\n source.address != \"127.0.0.1\" and source.address != \"::1\" and \n source.port >= 49152 and destination.port >= 49152\n ]\n\n /* Excluding Common FPs Nessus and SCCM */\n\n [process where event.type in (\"start\", \"process_started\") and process.parent.name : \"WmiPrvSE.exe\" and\n not process.args : (\"C:\\\\windows\\\\temp\\\\nessus_*.txt\", \n \"C:\\\\windows\\\\TEMP\\\\nessus_*.TMP\", \n \"C:\\\\Windows\\\\CCM\\\\SystemTemp\\\\*\", \n \"C:\\\\Windows\\\\CCMCache\\\\*\", \n \"C:\\\\CCM\\\\Cache\\\\*\")\n ]\n", "risk_score": 47, "rule_id": "f3475224-b179-4f78-8877-c2bd64c26b88", "severity": "medium", @@ -50,5 +50,5 @@ } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_powershell_remoting_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_powershell_remoting_target.json index 33b5ef7c0dacb..94708f90d20bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_powershell_remoting_target.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_powershell_remoting_target.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Incoming Execution via PowerShell Remoting", - "query": "sequence by host.id with maxspan = 30s\n [network where network.direction == \"incoming\" and destination.port in (5985, 5986) and\n network.protocol == \"http\" and source.address != \"127.0.0.1\" and source.address != \"::1\"\n ]\n [process where event.type == \"start\" and process.parent.name : \"wsmprovhost.exe\" and not process.name : \"conhost.exe\"]\n", + "query": "sequence by host.id with maxspan = 30s\n [network where network.direction : (\"incoming\", \"ingress\") and destination.port in (5985, 5986) and\n network.protocol == \"http\" and source.address != \"127.0.0.1\" and source.address != \"::1\"\n ]\n [process where event.type == \"start\" and process.parent.name : \"wsmprovhost.exe\" and not process.name : \"conhost.exe\"]\n", "references": [ "https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/running-remote-commands?view=powershell-7.1" ], @@ -47,5 +47,5 @@ } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json index 6b2f782e488c4..584f24cfb30f3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json @@ -35,12 +35,19 @@ { "id": "T1021", "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.001", + "name": "Remote Desktop Protocol", + "reference": "https://attack.mitre.org/techniques/T1021/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json index 0318883e374d3..0e5b7e7bc9001 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential SharpRDP Behavior", - "query": "/* Incoming RDP followed by a new RunMRU string value set to cmd, powershell, taskmgr or tsclient, followed by process execution within 1m */\n\nsequence by host.id with maxspan=1m\n [network where event.type == \"start\" and process.name : \"svchost.exe\" and destination.port == 3389 and \n network.direction == \"incoming\" and network.transport == \"tcp\" and\n source.address != \"127.0.0.1\" and source.address != \"::1\"\n ]\n\n [registry where process.name : \"explorer.exe\" and \n registry.path : (\"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\RunMRU\\\\*\") and\n registry.data.strings : (\"cmd.exe*\", \"powershell.exe*\", \"taskmgr*\", \"\\\\\\\\tsclient\\\\*.exe\\\\*\")\n ]\n \n [process where event.type in (\"start\", \"process_started\") and\n (process.parent.name : (\"cmd.exe\", \"powershell.exe\", \"taskmgr.exe\") or process.args : (\"\\\\\\\\tsclient\\\\*.exe\")) and \n not process.name : \"conhost.exe\"\n ]\n", + "query": "/* Incoming RDP followed by a new RunMRU string value set to cmd, powershell, taskmgr or tsclient, followed by process execution within 1m */\n\nsequence by host.id with maxspan=1m\n [network where event.type == \"start\" and process.name : \"svchost.exe\" and destination.port == 3389 and \n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\" and\n source.address != \"127.0.0.1\" and source.address != \"::1\"\n ]\n\n [registry where process.name : \"explorer.exe\" and \n registry.path : (\"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\RunMRU\\\\*\") and\n registry.data.strings : (\"cmd.exe*\", \"powershell.exe*\", \"taskmgr*\", \"\\\\\\\\tsclient\\\\*.exe\\\\*\")\n ]\n \n [process where event.type in (\"start\", \"process_started\") and\n (process.parent.name : (\"cmd.exe\", \"powershell.exe\", \"taskmgr.exe\") or process.args : (\"\\\\\\\\tsclient\\\\*.exe\")) and \n not process.name : \"conhost.exe\"\n ]\n", "references": [ "https://posts.specterops.io/revisiting-remote-desktop-lateral-movement-8fb905cb46c3", "https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES/blob/master/Lateral%20Movement/LM_sysmon_3_12_13_1_SharpRDP.evtx" @@ -39,11 +39,18 @@ { "id": "T1021", "name": "Remote Services", - "reference": "https://attack.mitre.org/techniques/T1021/" + "reference": "https://attack.mitre.org/techniques/T1021/", + "subtechnique": [ + { + "id": "T1021.001", + "name": "Remote Desktop Protocol", + "reference": "https://attack.mitre.org/techniques/T1021/001/" + } + ] } ] } ], "type": "eql", - "version": 2 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json index 88f5e0e63a052..5220506d37f58 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remotely Started Services via RPC", - "query": "sequence with maxspan=1s\n [network where process.name : \"services.exe\" and\n network.direction == \"incoming\" and network.transport == \"tcp\" and \n source.port >= 49152 and destination.port >= 49152 and source.address not in (\"127.0.0.1\", \"::1\")\n ] by host.id, process.entity_id\n\n [process where event.type in (\"start\", \"process_started\") and process.parent.name : \"services.exe\" and \n not (process.name : \"svchost.exe\" and process.args : \"tiledatamodelsvc\") and \n not (process.name : \"msiexec.exe\" and process.args : \"/V\")\n \n /* uncomment if psexec is noisy in your environment */\n /* and not process.name : \"PSEXESVC.exe\" */\n ] by host.id, process.parent.entity_id\n", + "query": "sequence with maxspan=1s\n [network where process.name : \"services.exe\" and\n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\" and \n source.port >= 49152 and destination.port >= 49152 and source.address not in (\"127.0.0.1\", \"::1\")\n ] by host.id, process.entity_id\n\n [process where event.type in (\"start\", \"process_started\") and process.parent.name : \"services.exe\" and \n not (process.name : \"svchost.exe\" and process.args : \"tiledatamodelsvc\") and \n not (process.name : \"msiexec.exe\" and process.args : \"/V\")\n \n /* uncomment if psexec is noisy in your environment */\n /* and not process.name : \"PSEXESVC.exe\" */\n ] by host.id, process.parent.entity_id\n", "risk_score": 47, "rule_id": "aa9a274d-6b53-424d-ac5e-cb8ca4251650", "severity": "medium", @@ -41,5 +41,5 @@ } ], "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json index b66b5a94fe27f..b60717e61765a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json @@ -12,8 +12,8 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote Scheduled Task Creation", - "note": "## Triage and analysis\n\nDecode the base64 encoded tasks actions registry value to investigate the task configured action.", - "query": "/* Task Scheduler service incoming connection followed by TaskCache registry modification */\n\nsequence by host.id, process.entity_id with maxspan = 1m\n [network where process.name : \"svchost.exe\" and\n network.direction == \"incoming\" and source.port >= 49152 and destination.port >= 49152 and\n source.address != \"127.0.0.1\" and source.address != \"::1\"\n ]\n [registry where registry.path : \"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*\\\\Actions\"]\n", + "note": "## Triage and analysis\n\n### Investigating Creation of Remote Scheduled Tasks\n\n[Scheduled tasks](https://docs.microsoft.com/en-us/windows/win32/taskschd/about-the-task-scheduler) are a great mechanism used for persistence and executing programs. These features can\nbe used remotely for a variety of legitimate reasons, but at the same time used by malware and adversaries.\nWhen investigating scheduled tasks that have been set-up remotely, one of the first methods should be determining the\noriginal intent behind the configuration and verify if the activity is tied to benign behavior such as software installations or any kind\nof network administrator work. One objective for these alerts is to understand the configured action within the scheduled\ntask, this is captured within the registry event data for this rule and can be base64 decoded to view the value.\n\n#### Possible investigation steps:\n- Review the base64 encoded tasks actions registry value to investigate the task configured action.\n- Determine if task is related to legitimate or benign behavior based on the corresponding process or program tied to the\nscheduled task.\n- Further examination should include both the source and target machines where host-based artifacts and network logs\nshould be reviewed further around the time window of the creation of the scheduled task.\n\n### False Positive Analysis\n- There is a high possibility of benign activity tied to the creation of remote scheduled tasks as it is a general feature\nwithin Windows and used for legitimate purposes for a wide range of activity. Any kind of context should be found to\nfurther understand the source of the activity and determine the intent based on the scheduled task contents.\n\n### Related Rules\n- Service Command Lateral Movement\n- Remotely Started Services via RPC\n\n### Response and Remediation\n- This behavior represents post-exploitation actions such as persistence or lateral movement, immediate response should\nbe taken to review and investigate the activity and potentially isolate involved machines to prevent further post-compromise\nbehavior.\n- Remove scheduled task and any other related artifacts to the activity.\n- Review privileged account management and user account management settings such as implementing GPO policies to further\nrestrict activity or configure settings that only allow Administrators to create remote scheduled tasks.\n", + "query": "/* Task Scheduler service incoming connection followed by TaskCache registry modification */\n\nsequence by host.id, process.entity_id with maxspan = 1m\n [network where process.name : \"svchost.exe\" and\n network.direction : (\"incoming\", \"ingress\") and source.port >= 49152 and destination.port >= 49152 and\n source.address != \"127.0.0.1\" and source.address != \"::1\"\n ]\n [registry where registry.path : \"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*\\\\Actions\"]\n", "risk_score": 47, "rule_id": "954ee7c8-5437-49ae-b2d6-2960883898e9", "severity": "medium", @@ -51,11 +51,18 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "type": "eql", - "version": 3 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_rare_user_logon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_rare_user_logon.json index 2f0a60b3efba9..d5d055bfa1658 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_rare_user_logon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_rare_user_logon.json @@ -3,7 +3,7 @@ "author": [ "Elastic" ], - "description": "A machine learning job found an unusual user name in the authentication logs. An unusual user name is one way of detecting credentialed access by means of a new or dormant user account. A user account that is normally inactive (because the user has left the organization) that becomes active may be due to credentialed access using a compromised account password. Threat actors will sometimes also create new users as a means of persisting in a compromised web application.", + "description": "A machine learning job found an unusual user name in the authentication logs. An unusual user name is one way of detecting credentialed access by means of a new or dormant user account. An inactive user account (because the user has left the organization) that becomes active may be due to credentialed access using a compromised account password. Threat actors will sometimes also create new users as a means of persisting in a compromised web application.", "false_positives": [ "User accounts that are rarely active, such as a site reliability engineer (SRE) or developer logging into a production server for troubleshooting, may trigger this alert. Under some conditions, a newly created user account may briefly trigger this alert while the model is learning." ], @@ -25,5 +25,5 @@ "ML" ], "type": "machine_learning", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_spike_in_logon_events_from_a_source_ip.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_spike_in_logon_events_from_a_source_ip.json index 8e007c96c37fb..ee9acc43ac8d7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_spike_in_logon_events_from_a_source_ip.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_auth_spike_in_logon_events_from_a_source_ip.json @@ -3,7 +3,7 @@ "author": [ "Elastic" ], - "description": "A machine learning job found an unusually large spike in successful authentication events events from a particular source IP address. This can be due to password spraying, user enumeration or brute force activity.", + "description": "A machine learning job found an unusually large spike in successful authentication events from a particular source IP address. This can be due to password spraying, user enumeration or brute force activity.", "false_positives": [ "Build servers and CI systems can sometimes trigger this alert. Security test cycles that include brute force or password spraying activities may trigger this alert." ], @@ -25,5 +25,5 @@ "ML" ], "type": "machine_learning", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json index e9ebbf2470b53..1b64f1d85301a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json @@ -12,7 +12,7 @@ "license": "Elastic License v2", "machine_learning_job_id": "high_distinct_count_error_message", "name": "Spike in AWS Error Messages", - "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating Spikes in CloudTrail Errors\nDetection alerts from this rule indicate a large spike in the number of CloudTrail log messages that contain a particular error message. The error message in question was associated with the response to an AWS API command or method call. Here are some possible avenues of investigation:\n- Examine the history of the error. Has it manifested before? If the error, which is visible in the `aws.cloudtrail.error_message` field, only manifested recently, it might be related to recent changes in an automation module or script.\n- Examine the request parameters. These may provide indications as to the nature of the task being performed when the error occurred. Is the error related to unsuccessful attempts to enumerate or access objects, data, or secrets? If so, this can sometimes be a byproduct of discovery, privilege escalation or lateral movement attempts.\n- Consider the user as identified by the user.name field. Is this activity part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key id in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating Spikes in CloudTrail Errors\n\nCloudTrail logging provides visibility on actions taken within an AWS environment. By monitoring these events and understanding\nwhat is considered normal behavior within an organization, suspicious or malicious activity can be spotted when deviations\nare observed. This example rule triggers from a large spike in the number of CloudTrail log messages that contain a\nparticular error message. The error message in question was associated with the response to an AWS API command or method call,\nthis has the potential to uncover unknown threats or activity.\n\n#### Possible investigation steps:\n- Examine the history of the error. Has it manifested before? If the error, which is visible in the `aws.cloudtrail.error_message` field, only manifested recently, it might be related to recent changes in an automation module or script.\n- Examine the request parameters. These may provide indications as to the nature of the task being performed when the error occurred. Is the error related to unsuccessful attempts to enumerate or access objects, data, or secrets? If so, this can sometimes be a byproduct of discovery, privilege escalation or lateral movement attempts.\n- Consider the user as identified by the `user.name field`. Is this activity part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key ID in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance that's not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n\n### False Positive Analysis\n- This rule has the possibility to produce false positives based on unexpected activity occurring such as bugs or recent\nchanges to automation modules or scripting.\n- Adoption of new services or implementing new functionality to scripts may generate false positives\n\n### Related Rules\n- Unusual AWS Command for a User\n- Rare AWS Error Code\n\n### Response and Remediation\n- If activity is observed as suspicious or malicious, immediate response should be looked into rotating and deleting AWS IAM access keys\n- Validate if any unauthorized new users were created, remove these accounts and request password resets for other IAM users\n- Look into enabling multi-factor authentication for users\n- Follow security best practices [outlined](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/) by AWS\n", "references": [ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html" ], @@ -26,5 +26,5 @@ "ML" ], "type": "machine_learning", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json index ac7a867f5cd6e..d9e2b3e358760 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json @@ -12,7 +12,7 @@ "license": "Elastic License v2", "machine_learning_job_id": "rare_error_code", "name": "Rare AWS Error Code", - "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\nInvestigating Unusual CloudTrail Error Activity ###\nDetection alerts from this rule indicate a rare and unusual error code that was associated with the response to an AWS API command or method call. Here are some possible avenues of investigation:\n- Examine the history of the error. Has it manifested before? If the error, which is visible in the `aws.cloudtrail.error_code field`, only manifested recently, it might be related to recent changes in an automation module or script.\n- Examine the request parameters. These may provide indications as to the nature of the task being performed when the error occurred. Is the error related to unsuccessful attempts to enumerate or access objects, data, or secrets? If so, this can sometimes be a byproduct of discovery, privilege escalation, or lateral movement attempts.\n- Consider the user as identified by the `user.name` field. Is this activity part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key id in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\nInvestigating Unusual CloudTrail Error Activity ###\nDetection alerts from this rule indicate a rare and unusual error code that was associated with the response to an AWS API command or method call. Here are some possible avenues of investigation:\n- Examine the history of the error. Has it manifested before? If the error, which is visible in the `aws.cloudtrail.error_code field`, only manifested recently, it might be related to recent changes in an automation module or script.\n- Examine the request parameters. These may provide indications as to the nature of the task being performed when the error occurred. Is the error related to unsuccessful attempts to enumerate or access objects, data, or secrets? If so, this can sometimes be a byproduct of discovery, privilege escalation, or lateral movement attempts.\n- Consider the user as identified by the `user.name` field. Is this activity part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key ID in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance that's not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?", "references": [ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html" ], @@ -26,5 +26,5 @@ "ML" ], "type": "machine_learning", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json index 2a31ce8c065d8..a3d6208eb9f05 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json @@ -12,7 +12,7 @@ "license": "Elastic License v2", "machine_learning_job_id": "rare_method_for_a_city", "name": "Unusual City For an AWS Command", - "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating an Unusual CloudTrail Event\nDetection alerts from this rule indicate an AWS API command or method call that is rare and unusual for the geolocation of the source IP address. Here are some possible avenues of investigation:\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n- Consider the user as identified by the `user.name` field. Is this command part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key id in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the time of day. If the user is a human, not a program or script, did the activity take place during a normal time of day?\n- Examine the history of the command. If the command, which is visible in the `event.action field`, only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, if it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process.\n- Examine the request parameters. These may provide indications as to the source of the program or the nature of the tasks it is performing.", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating an Unusual CloudTrail Event\nDetection alerts from this rule indicate an AWS API command or method call that is rare and unusual for the geolocation of the source IP address. Here are some possible avenues of investigation:\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance that's not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n- Consider the user as identified by the `user.name` field. Is this command part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key ID in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the time of day. If the user is a human, not a program or script, did the activity take place during a normal time of day?\n- Examine the history of the command. If the command, which is visible in the `event.action field`, only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, if it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process.\n- Examine the request parameters. These may provide indications as to the source of the program or the nature of the tasks it is performing.", "references": [ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html" ], @@ -26,5 +26,5 @@ "ML" ], "type": "machine_learning", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json index ebe7971e94289..4576b080e1ea6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json @@ -12,7 +12,7 @@ "license": "Elastic License v2", "machine_learning_job_id": "rare_method_for_a_country", "name": "Unusual Country For an AWS Command", - "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating an Unusual CloudTrail Event\nDetection alerts from this rule indicate an AWS API command or method call that is rare and unusual for the geolocation of the source IP address. Here are some possible avenues of investigation:\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n- Consider the user as identified by the `user.name` field. Is this command part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key id in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the time of day. If the user is a human, not a program or script, did the activity take place during a normal time of day?\n- Examine the history of the command. If the command, which is visible in the `event.action field`, only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, if it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process.\n- Examine the request parameters. These may provide indications as to the source of the program or the nature of the tasks it is performing.", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating an Unusual Country For an AWS Command\n\nCloudTrail logging provides visibility on actions taken within an AWS environment. By monitoring these events and understanding\nwhat is considered normal behavior within an organization, suspicious or malicious activity can be spotted when deviations\nare observed. This example rule focuses on AWS command activity where the country from the source of the activity has been\nconsidered unusual based on previous history.\n\n#### Possible investigation steps:\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance that's not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n- Consider the user as identified by the `user.name` field. Is this command part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key ID in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the time of day. If the user is a human, not a program or script, did the activity take place during a normal time of day?\n- Examine the history of the command. If the command, which is visible in the `event.action field`, only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, if it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process.\n- Examine the request parameters. These may provide indications as to the source of the program or the nature of the tasks it is performing.\n\n### False Positive Analysis\n- False positives can occur if activity is coming from new employees based in a country with no previous history in AWS,\ntherefore it's important to validate the activity listed in the investigation steps above.\n\n### Related Rules\n- Unusual City For an AWS Command\n- Unusual AWS Command for a User\n- Rare AWS Error Code\n\n### Response and Remediation\n- If activity is observed as suspicious or malicious, immediate response should be looked into rotating and deleting AWS IAM access keys\n- Validate if any unauthorized new users were created, remove these accounts and request password resets for other IAM users\n- Look into enabling multi-factor authentication for users\n- Follow security best practices [outlined](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/) by AWS\n", "references": [ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html" ], @@ -26,5 +26,5 @@ "ML" ], "type": "machine_learning", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json index ab9364c453423..53f9fab8d1b48 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json @@ -12,7 +12,7 @@ "license": "Elastic License v2", "machine_learning_job_id": "rare_method_for_a_username", "name": "Unusual AWS Command for a User", - "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating an Unusual CloudTrail Event\n\nDetection alerts from this rule indicate an AWS API command or method call that is rare and unusual for the calling IAM user. Here are some possible avenues of investigation:\n- Consider the user as identified by the `user.name` field. Is this command part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key id in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n- Consider the time of day. If the user is a human, not a program or script, did the activity take place during a normal time of day?\n- Examine the history of the command. If the command, which is visible in the `event.action field`, only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, if it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process.\n- Examine the request parameters. These may provide indications as to the source of the program or the nature of the tasks it is performing.", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n\n## Triage and analysis\n\n### Investigating an Unusual CloudTrail Event\n\nDetection alerts from this rule indicate an AWS API command or method call that is rare and unusual for the calling IAM user. Here are some possible avenues of investigation:\n- Consider the user as identified by the `user.name` field. Is this command part of an expected workflow for the user context? Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key ID in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context. The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.\n- Consider the source IP address and geolocation for the calling user who issued the command. Do they look normal for the calling user? If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts, or could it be sourcing from an EC2 instance that's not under your control? If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?\n- Consider the time of day. If the user is a human, not a program or script, did the activity take place during a normal time of day?\n- Examine the history of the command. If the command, which is visible in the `event.action field`, only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, if it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process.\n- Examine the request parameters. These may provide indications as to the source of the program or the nature of the tasks it is performing.", "references": [ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html" ], @@ -26,5 +26,5 @@ "ML" ], "type": "machine_learning", - "version": 6 + "version": 7 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_process_by_host_windows.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_process_by_host_windows.json index 8729de9a8689d..d8bf26884b16f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_process_by_host_windows.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_process_by_host_windows.json @@ -15,7 +15,7 @@ "v2_rare_process_by_host_windows_ecs" ], "name": "Unusual Process For a Windows Host", - "note": "## Triage and analysis\n\n### Investigating an Unusual Windows Process\nDetection alerts from this rule indicate the presence of a Windows process that is rare and unusual for the host it ran on. Here are some possible avenues of investigation:\n- Consider the user as identified by the username field. Is this program part of an expected workflow for the user who ran this program on this host?\n- Examine the history of execution. If this process only manifested recently, it might be part of a new software package. If it has a consistent cadence (for example if it runs monthly or quarterly), it might be part of a monthly or quarterly business process.\n- Examine the process metadata like the values of the Company, Description and Product fields which may indicate whether the program is associated with an expected software vendor or package.\n- Examine arguments and working directory. These may provide indications as to the source of the program or the nature of the tasks it is performing.\n- Consider the same for the parent process. If the parent process is a legitimate system utility or service, this could be related to software updates or system management. If the parent process is something user-facing like an Office application, this process could be more suspicious.\n- If you have file hash values in the event data, and you suspect malware, you can optionally run a search for the file hash to see if the file is identified as malware by anti-malware tools. ", + "note": "## Triage and analysis\n\n### Investigating an Unusual Windows Process\n\nSearching for abnormal Windows processes is a good methodology to find potentially malicious activity within a network.\nBy understanding what is commonly run within an environment and developing baselines for legitimate activity can help\nuncover potential malware and suspicious behaviors.\n\n#### Possible investigation steps:\n- Consider the user as identified by the `user.name` field. Is this program part of an expected workflow for the user who ran this program on this host?\n- Examine the history of execution. If this process only manifested recently, it might be part of a new software package. If it has a consistent cadence (for example if it runs monthly or quarterly), it might be part of a monthly or quarterly business process.\n- Examine the process metadata like the values of the Company, Description and Product fields which may indicate whether the program is associated with an expected software vendor or package.\n- Examine arguments and working directory. These may provide indications as to the source of the program or the nature of the tasks it is performing.\n- Consider the same for the parent process. If the parent process is a legitimate system utility or service, this could be related to software updates or system management. If the parent process is something user-facing like an Office application, this process could be more suspicious.\n- If you have file hash values in the event data, and you suspect malware, you can optionally run a search for the file hash to see if the file is identified as malware by anti-malware tools.\n\n### False Positive Analysis\n- Validate the unusual Windows process is not related to new benign software installation activity. If related to\nlegitimate software, this can be done by leveraging the exception workflow in the Kibana Security App or Elasticsearch\nAPI to tune this rule to your environment\n- Try to understand the context of the execution by thinking about the user, machine, or business purpose. It's possible that a small number of endpoints\nsuch as servers that have very unique software that might appear to be unusual, but satisfy a specific business need.\n\n### Related Rules\n- Anomalous Windows Process Creation\n- Unusual Windows Path Activity\n- Unusual Windows Process Calling the Metadata Service\n\n### Response and Remediation\n- This rule is related to process execution events and should be immediately reviewed and investigated to determine if malicious\n- Based on validation and if malicious, the impacted machine should be isolated and analyzed to determine other post-compromise\nbehavior such as setting up persistence or performing lateral movement.\n- Look into preventive measures such as Windows Defender Application Control and AppLocker to gain better control on\nwhat is allowed to run on Windows infrastructure.\n", "references": [ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html" ], @@ -30,5 +30,5 @@ "ML" ], "type": "machine_learning", - "version": 7 + "version": 8 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json index a3468f4a68948..b7421934ba8e8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json @@ -3,7 +3,7 @@ "Elastic", "Austin Songer" ], - "description": "Identifies a change to an AWS Security Group Configuration. A security group is like a virtul firewall and modifying configurations may allow unauthorized access. Threat actors may abuse this to establish persistence, exfiltrate data, or pivot in a AWS environment.", + "description": "Identifies a change to an AWS Security Group Configuration. A security group is like a virtual firewall, and modifying configurations may allow unauthorized access. Threat actors may abuse this to establish persistence, exfiltrate data, or pivot in an AWS environment.", "false_positives": [ "A security group may be created by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Security group creations from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." ], @@ -49,10 +49,23 @@ "name": "Defense Evasion", "reference": "https://attack.mitre.org/tactics/TA0005/" }, - "technique": [] + "technique": [ + { + "id": "T1562", + "name": "Impair Defenses", + "reference": "https://attack.mitre.org/techniques/T1562/", + "subtechnique": [ + { + "id": "T1562.007", + "name": "Disable or Modify Cloud Firewall", + "reference": "https://attack.mitre.org/techniques/T1562/007/" + } + ] + } + ] } ], "timestamp_override": "event.ingested", "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json index 8edaef5dc72fd..24f0f3d4d95b1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json @@ -39,12 +39,19 @@ { "id": "T1136", "name": "Create Account", - "reference": "https://attack.mitre.org/techniques/T1136/" + "reference": "https://attack.mitre.org/techniques/T1136/", + "subtechnique": [ + { + "id": "T1136.001", + "name": "Local Account", + "reference": "https://attack.mitre.org/techniques/T1136/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json index 947c1c748af69..21ad9c5161541 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious Startup Shell Folder Modification", - "note": "## Triage and analysis\n\nVerify file creation events in the new Windows Startup folder location.", + "note": "## Triage and analysis\n\n### Investigating Suspicious Startup Shell Activity\n\nTechniques used within malware and by adversaries often leverage the Windows registry to store malicious programs for\npersistence. Startup shell folders are often targeted as they are not as prevalent as normal Startup folder paths so this\nbehavior may evade existing AV/EDR solutions. Another preference is that these programs might run with higher privileges\nwhich can be ideal for an attacker.\n\n#### Possible investigation steps:\n- Review the source process and related file tied to the Windows Registry entry\n- Validate the activity is not related to planned patches, updates, network administrator activity or legitimate software\ninstallations\n- Determine if activity is unique by validating if other machines in same organization have similar entry\n\n### False Positive Analysis\n- There is a high possibility of benign legitimate programs being added to Shell folders. This activity could be based\non new software installations, patches, or any kind of network administrator related activity. Before entering further\ninvestigation, this activity should be validated that is it not related to benign activity\n\n### Related Rules\n- Startup or Run Key Registry Modification\n- Persistent Scripts in the Startup Directory\n\n### Response and Remediation\n- Activity should first be validated as a true positive event if so then immediate response should be taken to review,\ninvestigate and potentially isolate activity to prevent further post-compromise behavior\n- The respective binary or program tied to this persistence method should be further analyzed and reviewed to understand\nit's behavior and capabilities\n- Since this activity is considered post-exploitation behavior, it's important to understand how the behavior was first\ninitialized such as through a macro-enabled document that was attached in a phishing email. By understanding the source\nof the attack, this information can then be used to search for similar indicators on other machines in the same environment.\n", "query": "registry where\n registry.path : (\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\Common Startup\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\Common Startup\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\Startup\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\Startup\"\n ) and\n registry.data.strings != null and\n /* Normal Startup Folder Paths */\n not registry.data.strings : (\n \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"%ProgramData%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"%USERPROFILE%\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"C:\\\\Users\\\\*\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\"\n )\n", "risk_score": 73, "rule_id": "c8b150f0-0164-475b-a75e-74b47800a9ff", @@ -50,5 +50,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json new file mode 100644 index 0000000000000..e950569f19878 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json @@ -0,0 +1,57 @@ +{ + "author": [ + "Elastic", + "Austin Songer" + ], + "description": "Identifies the assignment of rights to accesss content from another mailbox. An adversary may use the compromised account to send messages to other accounts in the network of the target business while creating inbox rules, so messages can evade spam/phishing detection mechanisms.", + "false_positives": [ + "Assignment of rights to a service account." + ], + "index": [ + "filebeat-*", + "logs-o365*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "O365 Exchange Suspicious Mailbox Right Delegation", + "note": "## Config\n\nThe Microsoft 365 Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:o365.audit and event.provider:Exchange and event.action:Add-MailboxPermission and \no365.audit.Parameters.AccessRights:(FullAccess or SendAs or SendOnBehalf) and event.outcome:success\n", + "risk_score": 21, + "rule_id": "0ce6487d-8069-4888-9ddd-61b52490cebc", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "Microsoft 365", + "Continuous Monitoring", + "SecOps", + "Configuration Audit" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" + }, + "technique": [ + { + "id": "T1098", + "name": "Account Manipulation", + "reference": "https://attack.mitre.org/techniques/T1098/", + "subtechnique": [ + { + "id": "T1098.002", + "name": "Exchange Email Delegate Permissions", + "reference": "https://attack.mitre.org/techniques/T1098/002/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json index 86b1cd3e71eaf..ebbe2448c75df 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json @@ -35,12 +35,19 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json index 6e656209fd055..60afcad90333c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json @@ -38,12 +38,19 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_scripting.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_scripting.json index 712e98d4ac941..128fdd9de5575 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_scripting.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_scripting.json @@ -39,11 +39,18 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json similarity index 72% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json index 9a494a13fa297..75044e20ca5fd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_persistence_powershell_exch_mailbox_activesync_add_device.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json @@ -28,31 +28,33 @@ "Host", "Windows", "Threat Detection", - "Collection" + "Persistence" ], "threat": [ { "framework": "MITRE ATT&CK", "tactic": { - "id": "TA0009", - "name": "Collection", - "reference": "https://attack.mitre.org/tactics/TA0009/" + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" }, "technique": [ { - "id": "T1114", - "name": "Email Collection", - "reference": "https://attack.mitre.org/techniques/T1114/" - }, - { - "id": "T1005", - "name": "Data from Local System", - "reference": "https://attack.mitre.org/techniques/T1005/" + "id": "T1098", + "name": "Account Manipulation", + "reference": "https://attack.mitre.org/techniques/T1098/", + "subtechnique": [ + { + "id": "T1098.002", + "name": "Exchange Email Delegate Permissions", + "reference": "https://attack.mitre.org/techniques/T1098/002/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_instance_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_instance_creation.json index aa2c946d3a001..4ea6631025c11 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_instance_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_instance_creation.json @@ -1,6 +1,7 @@ { "author": [ - "Elastic" + "Elastic", + "Austin Songer" ], "description": "Identifies the creation of an Amazon Relational Database Service (RDS) Aurora database instance.", "false_positives": [ @@ -44,5 +45,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json index 7629ee4b821da..2b94ded55e7d4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json @@ -34,7 +34,20 @@ "name": "Persistence", "reference": "https://attack.mitre.org/tactics/TA0003/" }, - "technique": [] + "technique": [ + { + "id": "T1547", + "name": "Boot or Logon Autostart Execution", + "reference": "https://attack.mitre.org/techniques/T1547/", + "subtechnique": [ + { + "id": "T1547.001", + "name": "Registry Run Keys / Startup Folder", + "reference": "https://attack.mitre.org/techniques/T1547/001/" + } + ] + } + ] }, { "framework": "MITRE ATT&CK", @@ -54,5 +67,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_modified_or_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_modified_or_deleted.json new file mode 100644 index 0000000000000..54180a3a59a54 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_modified_or_deleted.json @@ -0,0 +1,55 @@ +{ + "author": [ + "Elastic", + "Austin Songer" + ], + "description": "Identifies when an AWS Route Table has been modified or deleted.", + "false_positives": [ + "Route Table could be modified or deleted by a system administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Route Table being modified from unfamiliar users should be investigated. If known behavior is causing false positives, it can be exempted from the rule. Also automated processes that uses Terraform may lead to false positives." + ], + "from": "now-60m", + "index": [ + "filebeat-*", + "logs-aws*" + ], + "interval": "10m", + "language": "kuery", + "license": "Elastic License v2", + "name": "AWS Route Table Modified or Deleted", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.action:(ReplaceRoute or ReplaceRouteTableAssociation or\nDeleteRouteTable or DeleteRoute or DisassociateRouteTable) and event.outcome:success\n", + "references": [ + "https://github.com/easttimor/aws-incident-response#network-routing", + "https://docs.datadoghq.com/security_platform/default_rules/cloudtrail-aws-route-table-modified", + "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ReplaceRoute.html", + "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ReplaceRouteTableAssociation", + "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteRouteTable.html", + "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteRoute.html", + "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DisassociateRouteTable.html" + ], + "risk_score": 21, + "rule_id": "e7cd5982-17c8-4959-874c-633acde7d426", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "AWS", + "Continuous Monitoring", + "SecOps", + "Network Security" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" + }, + "technique": [] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json new file mode 100644 index 0000000000000..544049d2c2df1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json @@ -0,0 +1,50 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies when a child process is spawned by the screensaver engine process, which is consistent with an attacker's malicious payload being executed after the screensaver activated on the endpoint. An adversary can maintain persistence on a macOS endpoint by creating a malicious screensaver (.saver) file and configuring the screensaver plist file to execute code each time the screensaver is activated.", + "from": "now-9m", + "index": [ + "auditbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Unexpected Child Process of macOS Screensaver Engine", + "note": "## Triage and analysis\n\n- Analyze the descendant processes of the ScreenSaverEngine process for malicious code and suspicious behavior such\nas downloading a payload from a server\n- Review the installed and activated screensaver on the host. Triage the screensaver (.saver) file that was triggered to\nidentify whether the file is malicious or not.\n", + "query": "process where event.type == \"start\" and process.parent.name == \"ScreenSaverEngine\"\n", + "references": [ + "https://posts.specterops.io/saving-your-access-d562bf5bf90b", + "https://github.com/D00MFist/PersistentJXA" + ], + "risk_score": 47, + "rule_id": "48d7f54d-c29e-4430-93a9-9db6b5892270", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "macOS", + "Threat Detection", + "Persistence" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" + }, + "technique": [ + { + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_plist_file_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_plist_file_modification.json new file mode 100644 index 0000000000000..dcd7427d7cbcd --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_plist_file_modification.json @@ -0,0 +1,50 @@ +{ + "author": [ + "Elastic" + ], + "description": "Identifies when a screensaver plist file is modified by an unexpected process. An adversary can maintain persistence on a macOS endpoint by creating a malicious screensaver (.saver) file and configuring the screensaver plist file to execute code each time the screensaver is activated.", + "from": "now-9m", + "index": [ + "auditbeat-*", + "logs-endpoint.events.*" + ], + "language": "eql", + "license": "Elastic License v2", + "name": "Screensaver Plist File Modified by Unexpected Process", + "note": "## Triage and analysis\n\n- Analyze the plist file modification event to identify whether the change was expected or not\n- Investigate the process that modified the plist file for malicious code or other suspicious behavior\n- Identify if any suspicious or known malicious screensaver (.saver) files were recently written to or modified on the host", + "query": "file where event.type != \"deletion\" and\n file.name: \"com.apple.screensaver.*.plist\" and\n file.path : (\n \"/Users/*/Library/Preferences/ByHost/*\",\n \"/Library/Managed Preferences/*\",\n \"/System/Library/Preferences/*\"\n ) and\n /* Filter OS processes modifying screensaver plist files */\n not process.executable : (\n \"/usr/sbin/cfprefsd\",\n \"/usr/libexec/xpcproxy\",\n \"/System/Library/CoreServices/ManagedClient.app/Contents/Resources/MCXCompositor\",\n \"/System/Library/CoreServices/ManagedClient.app/Contents/MacOS/ManagedClient\"\n )\n", + "references": [ + "https://posts.specterops.io/saving-your-access-d562bf5bf90b", + "https://github.com/D00MFist/PersistentJXA" + ], + "risk_score": 47, + "rule_id": "e6e8912f-283f-4d0d-8442-e0dcaf49944b", + "severity": "medium", + "tags": [ + "Elastic", + "Host", + "macOS", + "Threat Detection", + "Persistence" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0003", + "name": "Persistence", + "reference": "https://attack.mitre.org/tactics/TA0003/" + }, + "technique": [ + { + "id": "T1546", + "name": "Event Triggered Execution", + "reference": "https://attack.mitre.org/techniques/T1546/" + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "eql", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json index ea5917a246afe..812c35350677f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json @@ -38,12 +38,19 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json index c63d96b106a01..1e55f014806f3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json @@ -36,21 +36,14 @@ }, "technique": [ { - "id": "T1136", - "name": "Create Account", - "reference": "https://attack.mitre.org/techniques/T1136/", - "subtechnique": [ - { - "id": "T1136.001", - "name": "Local Account", - "reference": "https://attack.mitre.org/techniques/T1136/001/" - } - ] + "id": "T1098", + "name": "Account Manipulation", + "reference": "https://attack.mitre.org/techniques/T1098/" } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json index 0e2b01a1967d2..0777dfccab4bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json @@ -35,12 +35,19 @@ { "id": "T1136", "name": "Create Account", - "reference": "https://attack.mitre.org/techniques/T1136/" + "reference": "https://attack.mitre.org/techniques/T1136/", + "subtechnique": [ + { + "id": "T1136.001", + "name": "Local Account", + "reference": "https://attack.mitre.org/techniques/T1136/001/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 8 + "version": 9 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json index dca20728b40fa..0d9cd0cb4020a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json @@ -38,12 +38,19 @@ { "id": "T1053", "name": "Scheduled Task/Job", - "reference": "https://attack.mitre.org/techniques/T1053/" + "reference": "https://attack.mitre.org/techniques/T1053/", + "subtechnique": [ + { + "id": "T1053.005", + "name": "Scheduled Task", + "reference": "https://attack.mitre.org/techniques/T1053/005/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 5 + "version": 6 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json index fc3d94498d0cb..79e887a548bcb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json @@ -35,12 +35,19 @@ { "id": "T1546", "name": "Event Triggered Execution", - "reference": "https://attack.mitre.org/techniques/T1546/" + "reference": "https://attack.mitre.org/techniques/T1546/", + "subtechnique": [ + { + "id": "T1546.003", + "name": "Windows Management Instrumentation Event Subscription", + "reference": "https://attack.mitre.org/techniques/T1546/003/" + } + ] } ] } ], "timestamp_override": "event.ingested", "type": "eql", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json index 26248009f5a49..8da3be0b69d91 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json @@ -4,7 +4,7 @@ ], "description": "Identifies suspicious commands executed via a web server, which may suggest a vulnerability and remote shell access.", "false_positives": [ - "Security audits, maintenance and network administrative scripts may trigger this alert when run under web processes." + "Security audits, maintenance, and network administrative scripts may trigger this alert when run under web processes." ], "from": "now-9m", "index": [ @@ -71,5 +71,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json new file mode 100644 index 0000000000000..2a1231e96d8a5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json @@ -0,0 +1,61 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies a new or modified federation domain, which can be used to create a trust between O365 and an external identity provider.", + "index": [ + "filebeat-*", + "logs-o365*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "New or Modified Federation Domain", + "note": "## Config\n\nThe Microsoft 365 Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:(\"Set-AcceptedDomain\" or \n\"Set-MsolDomainFederationSettings\" or \"Add-FederatedDomain\" or \"New-AcceptedDomain\" or \"Remove-AcceptedDomain\" or \"Remove-FederatedDomain\") and \nevent.outcome:success\n", + "references": [ + "https://docs.microsoft.com/en-us/powershell/module/exchange/remove-accepteddomain?view=exchange-ps", + "https://docs.microsoft.com/en-us/powershell/module/exchange/remove-federateddomain?view=exchange-ps", + "https://docs.microsoft.com/en-us/powershell/module/exchange/new-accepteddomain?view=exchange-ps", + "https://docs.microsoft.com/en-us/powershell/module/exchange/add-federateddomain?view=exchange-ps", + "https://docs.microsoft.com/en-us/powershell/module/exchange/set-accepteddomain?view=exchange-ps", + "https://docs.microsoft.com/en-us/powershell/module/msonline/set-msoldomainfederationsettings?view=azureadps-1.0" + ], + "risk_score": 21, + "rule_id": "684554fc-0777-47ce-8c9b-3d01f198d7f8", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "Microsoft 365", + "Continuous Monitoring", + "SecOps", + "Identity and Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0004", + "name": "Privilege Escalation", + "reference": "https://attack.mitre.org/tactics/TA0004/" + }, + "technique": [ + { + "id": "T1484", + "name": "Domain Policy Modification", + "reference": "https://attack.mitre.org/techniques/T1484/", + "subtechnique": [ + { + "id": "T1484.002", + "name": "Domain Trust Modification", + "reference": "https://attack.mitre.org/techniques/T1484/002/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json new file mode 100644 index 0000000000000..c5e2669c1fade --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json @@ -0,0 +1,74 @@ +{ + "author": [ + "Austin Songer" + ], + "description": "Identifies the suspicious use of GetSessionToken. Tokens could be created and used by attackers to move laterally and escalate privileges.", + "false_positives": [ + "GetSessionToken may be done by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. GetSessionToken from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule." + ], + "index": [ + "filebeat-*", + "logs-aws*" + ], + "language": "kuery", + "license": "Elastic License v2", + "name": "AWS STS GetSessionToken Abuse", + "note": "## Config\n\nThe AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.", + "query": "event.dataset:aws.cloudtrail and event.provider:sts.amazonaws.com and event.action:GetSessionToken and \naws.cloudtrail.user_identity.type:IAMUser and event.outcome:success\n", + "references": [ + "https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html" + ], + "risk_score": 21, + "rule_id": "b45ab1d2-712f-4f01-a751-df3826969807", + "severity": "low", + "tags": [ + "Elastic", + "Cloud", + "AWS", + "Continuous Monitoring", + "SecOps", + "Identity and Access" + ], + "threat": [ + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0004", + "name": "Privilege Escalation", + "reference": "https://attack.mitre.org/tactics/TA0004/" + }, + "technique": [ + { + "id": "T1548", + "name": "Abuse Elevation Control Mechanism", + "reference": "https://attack.mitre.org/techniques/T1548/" + } + ] + }, + { + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0008", + "name": "Lateral Movement", + "reference": "https://attack.mitre.org/tactics/TA0008/" + }, + "technique": [ + { + "id": "T1550", + "name": "Use Alternate Authentication Material", + "reference": "https://attack.mitre.org/techniques/T1550/", + "subtechnique": [ + { + "id": "T1550.001", + "name": "Application Access Token", + "reference": "https://attack.mitre.org/techniques/T1550/001/" + } + ] + } + ] + } + ], + "timestamp_override": "event.ingested", + "type": "query", + "version": 1 +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json index 9cdf474efb450..d9b7280392f38 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json @@ -14,7 +14,7 @@ "name": "Unusual Parent-Child Relationship", "query": "process where event.type in (\"start\", \"process_started\") and\nprocess.parent.name != null and\n (\n /* suspicious parent processes */\n (process.name:\"autochk.exe\" and not process.parent.name:\"smss.exe\") or\n (process.name:(\"fontdrvhost.exe\", \"dwm.exe\") and not process.parent.name:(\"wininit.exe\", \"winlogon.exe\")) or\n (process.name:(\"consent.exe\", \"RuntimeBroker.exe\", \"TiWorker.exe\") and not process.parent.name:\"svchost.exe\") or\n (process.name:\"SearchIndexer.exe\" and not process.parent.name:\"services.exe\") or\n (process.name:\"SearchProtocolHost.exe\" and not process.parent.name:(\"SearchIndexer.exe\", \"dllhost.exe\")) or\n (process.name:\"dllhost.exe\" and not process.parent.name:(\"services.exe\", \"svchost.exe\")) or\n (process.name:\"smss.exe\" and not process.parent.name:(\"System\", \"smss.exe\")) or\n (process.name:\"csrss.exe\" and not process.parent.name:(\"smss.exe\", \"svchost.exe\")) or\n (process.name:\"wininit.exe\" and not process.parent.name:\"smss.exe\") or\n (process.name:\"winlogon.exe\" and not process.parent.name:\"smss.exe\") or\n (process.name:(\"lsass.exe\", \"LsaIso.exe\") and not process.parent.name:\"wininit.exe\") or\n (process.name:\"LogonUI.exe\" and not process.parent.name:(\"wininit.exe\", \"winlogon.exe\")) or\n (process.name:\"services.exe\" and not process.parent.name:\"wininit.exe\") or\n (process.name:\"svchost.exe\" and not process.parent.name:(\"MsMpEng.exe\", \"services.exe\")) or\n (process.name:\"spoolsv.exe\" and not process.parent.name:\"services.exe\") or\n (process.name:\"taskhost.exe\" and not process.parent.name:(\"services.exe\", \"svchost.exe\")) or\n (process.name:\"taskhostw.exe\" and not process.parent.name:(\"services.exe\", \"svchost.exe\")) or\n (process.name:\"userinit.exe\" and not process.parent.name:(\"dwm.exe\", \"winlogon.exe\")) or\n (process.name:(\"wmiprvse.exe\", \"wsmprovhost.exe\", \"winrshost.exe\") and not process.parent.name:\"svchost.exe\") or\n /* suspicious child processes */\n (process.parent.name:(\"SearchProtocolHost.exe\", \"taskhost.exe\", \"csrss.exe\") and not process.name:(\"werfault.exe\", \"wermgr.exe\", \"WerFaultSecure.exe\")) or\n (process.parent.name:\"autochk.exe\" and not process.name:(\"chkdsk.exe\", \"doskey.exe\", \"WerFault.exe\")) or\n (process.parent.name:\"smss.exe\" and not process.name:(\"autochk.exe\", \"smss.exe\", \"csrss.exe\", \"wininit.exe\", \"winlogon.exe\", \"setupcl.exe\", \"WerFault.exe\")) or\n (process.parent.name:\"wermgr.exe\" and not process.name:(\"WerFaultSecure.exe\", \"wermgr.exe\", \"WerFault.exe\")) or\n (process.parent.name:\"conhost.exe\" and not process.name:(\"mscorsvw.exe\", \"wermgr.exe\", \"WerFault.exe\", \"WerFaultSecure.exe\"))\n )\n", "references": [ - "https://github.com/sbousseaden/Slides/blob/master/Hunting MindMaps/PNG/Windows Processes%20TH.map.png", + "https://github.com/sbousseaden/Slides/blob/master/Hunting%20MindMaps/PNG/Windows%20Processes%20TH.map.png", "https://www.andreafortuna.org/2017/06/15/standard-windows-processes-a-brief-reference/" ], "risk_score": 47, @@ -53,5 +53,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 9 + "version": 10 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json index f582eba053d64..e4b1309c42644 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json @@ -16,7 +16,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "Threat Intel Filebeat Module Indicator Match", - "note": "## Triage and Analysis\n\nIf an indicator matches a local observation, the following enriched fields will be generated to identify the indicator, field, and type matched.\n\n- `threatintel.indicator.matched.atomic` - this identifies the atomic indicator that matched the local observation\n- `threatintel.indicator.matched.field` - this identifies the indicator field that matched the local observation\n- `threatintel.indicator.matched.type` - this identifies the indicator type that matched the local observation\n", + "note": "## Triage and Analysis\n\n### Investigating Threat Intel Indicator Matches\n\nThreat Intel indicator match rules allow matching from a local observation such as an endpoint event that records a file\nhash with an entry of a file hash stored within the Threat Intel Filebeat module. Other examples of matches can occur on\nan IP address, registry path, URL and imphash.\n\nThe matches will be based on the incoming feed data so it's important to validate the data and review the results by\ninvestigating the associated activity to determine if it requires further investigation.\n\nIf an indicator matches a local observation, the following enriched fields will be generated to identify the indicator, field, and type matched.\n\n- `threatintel.indicator.matched.atomic` - this identifies the atomic indicator that matched the local observation\n- `threatintel.indicator.matched.field` - this identifies the indicator field that matched the local observation\n- `threatintel.indicator.matched.type` - this identifies the indicator type that matched the local observation\n\n#### Possible investigation steps:\n- Investigation should be validated and reviewed based on the data (file hash, registry path, URL, imphash) that was matched\nand viewing the source of that activity.\n- Consider the history of the indicator that was matched. Has it happened before? Is it happening on multiple machines?\nThese kinds of questions can help understand if the activity is related to legitimate behavior.\n- Consider the user and their role within the company, is this something related to their job or work function?\n\n### False Positive Analysis\n- For any matches found, it's important to consider the initial release date of that indicator. Threat intelligence can\nbe a great tool for augmenting existing security processes, while at the same time it should be understood that threat\nintelligence can represent a specific set of activity observed at a point in time. For example, an IP address\nmay have hosted malware observed in a Dridex campaign six months ago, but it's possible that IP has been remediated and\nno longer represents any threat.\n- Adversaries often use legitimate tools as network administrators such as `PsExec` or `AdFind`, these tools often find their\nway into indicator lists creating the potential for false positives.\n- It's possible after large and publicly written campaigns, curious employees might end up going directly to attacker infrastructure and generating these rules\n\n### Response and Remediation\n- If suspicious or malicious behavior is observed, immediate response should be taken to isolate activity to prevent further\npost-compromise behavior.\n- One example of a response if a machine matched a command and control IP address would be to add an entry to a network\ndevice such as a firewall or proxy appliance to prevent any outbound activity from leaving that machine.\n- Another example of a response with a malicious file hash match would involve validating if the file was properly quarantined,\nreview current running processes looking for any abnormal activity, and investigating for any other follow-up actions such as persistence or lateral movement\n", "query": "file.hash.*:* or file.pe.imphash:* or source.ip:* or destination.ip:* or url.full:* or registry.path:*\n", "references": [ "https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-threatintel.html" @@ -190,9 +190,9 @@ ] } ], - "threat_query": "event.module:threatintel and (threatintel.indicator.file.hash.*:* or threatintel.indicator.file.pe.imphash:* or threatintel.indicator.ip:* or threatintel.indicator.registry.path:* or threatintel.indicator.url.full:*)", + "threat_query": "@timestamp >= \"now-30d\" and event.module:threatintel and (threatintel.indicator.file.hash.*:* or threatintel.indicator.file.pe.imphash:* or threatintel.indicator.ip:* or threatintel.indicator.registry.path:* or threatintel.indicator.url.full:*)", "timeline_id": "495ad7a7-316e-4544-8a0f-9c098daee76e", "timeline_title": "Generic Threat Match Timeline", "type": "threat_match", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts index 6f89d725a458e..2e17b91fbcd54 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts @@ -7,7 +7,11 @@ import { readRules } from './read_rules'; import { rulesClientMock } from '../../../../../alerting/server/mocks'; -import { getAlertMock, getFindResultWithSingleHit } from '../routes/__mocks__/request_responses'; +import { + resolveAlertMock, + getAlertMock, + getFindResultWithSingleHit, +} from '../routes/__mocks__/request_responses'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; export class TestError extends Error { @@ -33,7 +37,9 @@ describe.each([ describe('readRules', () => { test('should return the output from rulesClient if id is set but ruleId is undefined', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockResolvedValue(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); + rulesClient.resolve.mockResolvedValue( + resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + ); const rule = await readRules({ isRuleRegistryEnabled, @@ -45,10 +51,10 @@ describe.each([ }); test('should return null if saved object found by alerts client given id is not alert type', async () => { const rulesClient = rulesClientMock.create(); - const result = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result = resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); // @ts-expect-error delete result.alertTypeId; - rulesClient.get.mockResolvedValue(result); + rulesClient.resolve.mockResolvedValue(result); const rule = await readRules({ isRuleRegistryEnabled, @@ -61,7 +67,7 @@ describe.each([ test('should return error if alerts client throws 404 error on get', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockImplementation(() => { + rulesClient.resolve.mockImplementation(() => { throw new TestError(); }); @@ -76,7 +82,7 @@ describe.each([ test('should return error if alerts client throws error on get', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockImplementation(() => { + rulesClient.resolve.mockImplementation(() => { throw new Error('Test error'); }); try { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts index 9578e3d4cb6d2..2571791164b6b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { SanitizedAlert } from '../../../../../alerting/common'; +import { ResolvedSanitizedRule, SanitizedAlert } from '../../../../../alerting/common'; import { INTERNAL_RULE_ID_KEY } from '../../../../common/constants'; import { RuleParams } from '../schemas/rule_schemas'; import { findRules } from './find_rules'; @@ -24,11 +24,17 @@ export const readRules = async ({ rulesClient, id, ruleId, -}: ReadRuleOptions): Promise<SanitizedAlert<RuleParams> | null> => { +}: ReadRuleOptions): Promise< + SanitizedAlert<RuleParams> | ResolvedSanitizedRule<RuleParams> | null +> => { if (id != null) { try { - const rule = await rulesClient.get({ id }); + const rule = await rulesClient.resolve({ id }); if (isAlertType(isRuleRegistryEnabled, rule)) { + if (rule?.outcome === 'exactMatch') { + const { outcome, ...restOfRule } = rule; + return restOfRule; + } return rule; } else { return null; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/saved_object_mappings.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/saved_object_mappings.ts index 813e800f34ce2..d347fccf6b77b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/saved_object_mappings.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/saved_object_mappings.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { SavedObjectsType } from '../../../../../../../src/core/server'; +import { SavedObjectsType, SavedObjectMigrationFn } from 'kibana/server'; +import { truncateMessage } from '../rule_execution_log'; export const ruleStatusSavedObjectType = 'siem-detection-engine-rule-status'; @@ -47,11 +48,28 @@ export const ruleStatusSavedObjectMappings: SavedObjectsType['mappings'] = { }, }; +const truncateMessageFields: SavedObjectMigrationFn<Record<string, unknown>> = (doc) => { + const { lastFailureMessage, lastSuccessMessage, ...restAttributes } = doc.attributes; + + return { + ...doc, + attributes: { + lastFailureMessage: truncateMessage(lastFailureMessage), + lastSuccessMessage: truncateMessage(lastSuccessMessage), + ...restAttributes, + }, + references: doc.references ?? [], + }; +}; + export const type: SavedObjectsType = { name: ruleStatusSavedObjectType, hidden: false, namespaceType: 'single', mappings: ruleStatusSavedObjectMappings, + migrations: { + '7.15.2': truncateMessageFields, + }, }; export const ruleAssetSavedObjectType = 'security-rule'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts index cceda063e987b..8adf19a53f92b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts @@ -100,14 +100,14 @@ import { } from '../../../../common/detection_engine/schemas/common/schemas'; import { RulesClient, PartialAlert } from '../../../../../alerting/server'; -import { Alert, SanitizedAlert } from '../../../../../alerting/common'; +import { SanitizedAlert } from '../../../../../alerting/common'; import { SIGNALS_ID } from '../../../../common/constants'; import { PartialFilter } from '../types'; import { RuleParams } from '../schemas/rule_schemas'; import { IRuleExecutionLogClient } from '../rule_execution_log/types'; import { ruleTypeMappings } from '../signals/utils'; -export type RuleAlertType = Alert<RuleParams>; +export type RuleAlertType = SanitizedAlert<RuleParams>; // eslint-disable-next-line @typescript-eslint/no-explicit-any export interface IRuleStatusSOAttributes extends Record<string, any> { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts index 74301f3665ff8..703be3bdd76bd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { getAlertMock } from '../routes/__mocks__/request_responses'; +import { getAlertMock, resolveAlertMock } from '../routes/__mocks__/request_responses'; import { updateRules } from './update_rules'; import { getUpdateRulesOptionsMock, getUpdateMlRulesOptionsMock } from './update_rules.mock'; import { RulesClientMock } from '../../../../../alerting/server/rules_client.mock'; @@ -18,8 +18,8 @@ describe.each([ it('should call rulesClient.disable if the rule was enabled and enabled is false', async () => { const rulesOptionsMock = getUpdateRulesOptionsMock(isRuleRegistryEnabled); rulesOptionsMock.ruleUpdate.enabled = false; - (rulesOptionsMock.rulesClient as unknown as RulesClientMock).get.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + (rulesOptionsMock.rulesClient as unknown as RulesClientMock).resolve.mockResolvedValue( + resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) ); (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) @@ -38,8 +38,8 @@ describe.each([ const rulesOptionsMock = getUpdateRulesOptionsMock(isRuleRegistryEnabled); rulesOptionsMock.ruleUpdate.enabled = true; - (rulesOptionsMock.rulesClient as unknown as RulesClientMock).get.mockResolvedValue({ - ...getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + (rulesOptionsMock.rulesClient as unknown as RulesClientMock).resolve.mockResolvedValue({ + ...resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), enabled: false, }); (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( @@ -63,8 +63,8 @@ describe.each([ getAlertMock(isRuleRegistryEnabled, getMlRuleParams()) ); - (rulesOptionsMock.rulesClient as unknown as RulesClientMock).get.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getMlRuleParams()) + (rulesOptionsMock.rulesClient as unknown as RulesClientMock).resolve.mockResolvedValue( + resolveAlertMock(isRuleRegistryEnabled, getMlRuleParams()) ); await updateRules(rulesOptionsMock); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts index eef20af0e564d..240a226e86914 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts @@ -27,7 +27,7 @@ import { AppClient } from '../../../types'; import { addTags } from '../rules/add_tags'; import { DEFAULT_MAX_SIGNALS, SERVER_APP_ID, SIGNALS_ID } from '../../../../common/constants'; import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; -import { SanitizedAlert } from '../../../../../alerting/common'; +import { ResolvedSanitizedRule, SanitizedAlert } from '../../../../../alerting/common'; import { IRuleStatusSOAttributes } from '../rules/types'; import { transformTags } from '../routes/rules/utils'; import { RuleExecutionStatus } from '../../../../common/detection_engine/schemas/common/schemas'; @@ -281,12 +281,17 @@ export const commonParamsCamelToSnake = (params: BaseRuleParams) => { }; export const internalRuleToAPIResponse = ( - rule: SanitizedAlert<RuleParams>, + rule: SanitizedAlert<RuleParams> | ResolvedSanitizedRule<RuleParams>, ruleStatus?: IRuleStatusSOAttributes, legacyRuleActions?: LegacyRuleActions | null ): FullResponseSchema => { const mergedStatus = ruleStatus ? mergeAlertWithSidecarStatus(rule, ruleStatus) : undefined; + const isResolvedRule = (obj: unknown): obj is ResolvedSanitizedRule<RuleParams> => + (obj as ResolvedSanitizedRule<RuleParams>).outcome != null; return { + // saved object properties + outcome: isResolvedRule(rule) ? rule.outcome : undefined, + alias_target_id: isResolvedRule(rule) ? rule.alias_target_id : undefined, // Alerting framework params id: rule.id, updated_at: rule.updatedAt.toISOString(), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts index 1e3a8a513c4a1..2094264cbf15f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts @@ -69,7 +69,7 @@ import { wrapSequencesFactory } from './wrap_sequences_factory'; import { ConfigType } from '../../../config'; import { ExperimentalFeatures } from '../../../../common/experimental_features'; import { injectReferences, extractReferences } from './saved_object_references'; -import { RuleExecutionLogClient } from '../rule_execution_log/rule_execution_log_client'; +import { RuleExecutionLogClient, truncateMessageList } from '../rule_execution_log'; import { RuleExecutionStatus } from '../../../../common/detection_engine/schemas/common/schemas'; import { scheduleThrottledNotificationActions } from '../notifications/schedule_throttle_notification_actions'; import { IEventLogService } from '../../../../../event_log/server'; @@ -384,7 +384,9 @@ export const signalRulesAlertType = ({ throw new Error(`unknown rule type ${type}`); } if (result.warningMessages.length) { - const warningMessage = buildRuleMessage(result.warningMessages.join()); + const warningMessage = buildRuleMessage( + truncateMessageList(result.warningMessages).join() + ); await ruleStatusClient.logStatusChange({ ...basicLogArguments, newStatus: RuleExecutionStatus['partial failure'], @@ -471,7 +473,7 @@ export const signalRulesAlertType = ({ } else { const errorMessage = buildRuleMessage( 'Bulk Indexing of signals failed:', - result.errors.join() + truncateMessageList(result.errors).join() ); logger.error(errorMessage); await ruleStatusClient.logStatusChange({ diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts b/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts new file mode 100644 index 0000000000000..45ceb98ed0dc1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ConcreteTaskInstance, TaskStatus } from '../../../../../task_manager/server'; +import { TelemetryEventsSender } from '../sender'; +import { TelemetryReceiver } from '../receiver'; +import { SecurityTelemetryTaskConfig } from '../task'; +import { PackagePolicy } from '../../../../../fleet/common/types/models/package_policy'; + +/** + * Creates a mocked Telemetry Events Sender + */ +export const createMockTelemetryEventsSender = ( + enableTelemetry?: boolean +): jest.Mocked<TelemetryEventsSender> => { + return { + setup: jest.fn(), + start: jest.fn(), + stop: jest.fn(), + fetchTelemetryUrl: jest.fn(), + queueTelemetryEvents: jest.fn(), + processEvents: jest.fn(), + isTelemetryOptedIn: jest.fn().mockReturnValue(enableTelemetry ?? jest.fn()), + sendIfDue: jest.fn(), + sendEvents: jest.fn(), + } as unknown as jest.Mocked<TelemetryEventsSender>; +}; + +export const createMockTelemetryReceiver = ( + diagnosticsAlert?: unknown +): jest.Mocked<TelemetryReceiver> => { + return { + start: jest.fn(), + fetchClusterInfo: jest.fn(), + fetchLicenseInfo: jest.fn(), + copyLicenseFields: jest.fn(), + fetchFleetAgents: jest.fn(), + fetchDiagnosticAlerts: jest.fn().mockReturnValue(diagnosticsAlert ?? jest.fn()), + fetchEndpointMetrics: jest.fn(), + fetchEndpointPolicyResponses: jest.fn(), + fetchTrustedApplications: jest.fn(), + fetchEndpointList: jest.fn(), + fetchDetectionRules: jest.fn().mockReturnValue({ body: null }), + } as unknown as jest.Mocked<TelemetryReceiver>; +}; + +/** + * Creates a mocked package policy + */ +export const createMockPackagePolicy = (): jest.Mocked<PackagePolicy> => { + return { + id: jest.fn(), + inputs: jest.fn(), + version: jest.fn(), + revision: jest.fn(), + updated_at: jest.fn(), + updated_by: jest.fn(), + created_at: jest.fn(), + created_by: jest.fn(), + } as unknown as jest.Mocked<PackagePolicy>; +}; + +/** + * Creates a mocked Security Telemetry Task Config + */ +export const createMockSecurityTelemetryTask = ( + testType?: string, + testLastTimestamp?: string +): jest.Mocked<SecurityTelemetryTaskConfig> => { + return { + type: testType, + title: 'test title', + interval: '0m', + timeout: '0m', + version: '0.0.0', + getLastExecutionTime: jest.fn().mockReturnValue(testLastTimestamp ?? jest.fn()), + runTask: jest.fn(), + } as unknown as jest.Mocked<SecurityTelemetryTaskConfig>; +}; + +/** + * Creates a mocked Task Instance + */ +export const createMockTaskInstance = (testId: string, testType: string): ConcreteTaskInstance => { + return { + id: testId, + runAt: new Date(), + attempts: 0, + ownerId: '', + status: TaskStatus.Running, + startedAt: new Date(), + scheduledAt: new Date(), + retryAt: new Date(), + params: {}, + state: {}, + taskType: testType, + } as ConcreteTaskInstance; +}; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts index 91f83d5e7cb37..ec1505ec314d1 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts @@ -7,6 +7,12 @@ export const TELEMETRY_MAX_BUFFER_SIZE = 100; +export const MAX_SECURITY_LIST_TELEMETRY_BATCH = 100; + +export const MAX_ENDPOINT_TELEMETRY_BATCH = 1_000; + +export const MAX_DETECTION_RULE_TELEMETRY_BATCH = 1_000; + export const TELEMETRY_CHANNEL_LISTS = 'security-lists-v2'; export const TELEMETRY_CHANNEL_ENDPOINT_META = 'endpoint-metadata'; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/filters.ts b/x-pack/plugins/security_solution/server/lib/telemetry/filters.ts index a29f195ed5ecc..ee162fb76f95b 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/filters.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/filters.ts @@ -14,6 +14,7 @@ export interface AllowlistFields { // Allow list process fields within events. This includes "process" and "Target.process".' const allowlistProcessFields: AllowlistFields = { args: true, + entity_id: true, name: true, executable: true, code_signature: true, @@ -30,6 +31,9 @@ const allowlistProcessFields: AllowlistFields = { dll: true, malware_signature: true, memory_region: true, + real: { + entity_id: true, + }, token: { integrity_level_name: true, }, @@ -49,6 +53,7 @@ const allowlistBaseEventFields: AllowlistFields = { original_file_name: true, }, }, + dns: true, event: true, file: { extension: true, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts index 528082d8cb5b1..77c78c4dba28d 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts @@ -6,7 +6,7 @@ */ import moment from 'moment'; -import { createMockPackagePolicy } from './mocks'; +import { createMockPackagePolicy } from './__mocks__'; import { LIST_DETECTION_RULE_EXCEPTION, LIST_ENDPOINT_EXCEPTION, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/mocks.ts b/x-pack/plugins/security_solution/server/lib/telemetry/mocks.ts deleted file mode 100644 index 9168683141e48..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/telemetry/mocks.ts +++ /dev/null @@ -1,90 +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. - */ - -// eslint-disable-next-line max-classes-per-file -import { TelemetryEventsSender } from './sender'; -import { TelemetryReceiver } from './receiver'; -import { DiagnosticTask, EndpointTask, ExceptionListsTask, DetectionRulesTask } from './tasks'; -import { PackagePolicy } from '../../../../fleet/common/types/models/package_policy'; - -/** - * Creates a mocked Telemetry Events Sender - */ -export const createMockTelemetryEventsSender = ( - enableTelemtry: boolean -): jest.Mocked<TelemetryEventsSender> => { - return { - setup: jest.fn(), - start: jest.fn(), - stop: jest.fn(), - fetchTelemetryUrl: jest.fn(), - queueTelemetryEvents: jest.fn(), - processEvents: jest.fn(), - isTelemetryOptedIn: jest.fn().mockReturnValue(enableTelemtry ?? jest.fn()), - sendIfDue: jest.fn(), - sendEvents: jest.fn(), - } as unknown as jest.Mocked<TelemetryEventsSender>; -}; - -export const createMockTelemetryReceiver = (): jest.Mocked<TelemetryReceiver> => { - return { - start: jest.fn(), - fetchClusterInfo: jest.fn(), - fetchLicenseInfo: jest.fn(), - copyLicenseFields: jest.fn(), - fetchDiagnosticAlerts: jest.fn(), - fetchEndpointMetrics: jest.fn(), - fetchEndpointPolicyResponses: jest.fn(), - fetchTrustedApplications: jest.fn(), - fetchDetectionRules: jest.fn(), - fetchDetectionExceptionList: jest.fn(), - } as unknown as jest.Mocked<TelemetryReceiver>; -}; - -/** - * Creates a mocked package policy - */ -export const createMockPackagePolicy = (): jest.Mocked<PackagePolicy> => { - return { - id: jest.fn(), - inputs: jest.fn(), - version: jest.fn(), - revision: jest.fn(), - updated_at: jest.fn(), - updated_by: jest.fn(), - created_at: jest.fn(), - created_by: jest.fn(), - } as unknown as jest.Mocked<PackagePolicy>; -}; - -/** - * Creates a mocked Telemetry Diagnostic Task - */ -export class MockTelemetryDiagnosticTask extends DiagnosticTask { - public runTask = jest.fn(); -} - -/** - * Creates a mocked Telemetry Endpoint Task - */ -export class MockTelemetryEndpointTask extends EndpointTask { - public runTask = jest.fn(); -} - -/** - * Creates a mocked Telemetry exception lists Task - */ -export class MockExceptionListsTask extends ExceptionListsTask { - public runTask = jest.fn(); -} - -/** - * Creates a mocked Telemetry detection rules lists Task - */ -export class MockDetectionRuleListsTask extends DetectionRulesTask { - public runTask = jest.fn(); -} diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/sender.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/sender.test.ts index 21e6b2cf6d9c4..46ed0b1f0bfb6 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/sender.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/sender.test.ts @@ -36,6 +36,11 @@ describe('TelemetryEventsSender', () => { event: { kind: 'alert', }, + dns: { + question: { + name: 'test-dns', + }, + }, agent: { name: 'test', }, @@ -79,6 +84,7 @@ describe('TelemetryEventsSender', () => { nope: 'nope', executable: null, // null fields are never allowlisted working_directory: '/some/usr/dir', + entity_id: 'some_entity_id', }, Responses: '{ "result": 0 }', // >= 7.15 Target: { @@ -102,6 +108,11 @@ describe('TelemetryEventsSender', () => { event: { kind: 'alert', }, + dns: { + question: { + name: 'test-dns', + }, + }, agent: { name: 'test', }, @@ -139,6 +150,7 @@ describe('TelemetryEventsSender', () => { process: { name: 'foo.exe', working_directory: '/some/usr/dir', + entity_id: 'some_entity_id', }, Responses: '{ "result": 0 }', Target: { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts b/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts index b0792ed7b4610..7c9906d0eae48 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts @@ -8,20 +8,22 @@ import { cloneDeep } from 'lodash'; import axios from 'axios'; import { URL } from 'url'; +import { transformDataToNdjson } from '@kbn/securitysolution-utils'; + import { Logger } from 'src/core/server'; import { TelemetryPluginStart, TelemetryPluginSetup } from 'src/plugins/telemetry/server'; import { UsageCounter } from 'src/plugins/usage_collection/server'; -import { transformDataToNdjson } from '../../utils/read_stream/create_stream_from_ndjson'; import { TaskManagerSetupContract, TaskManagerStartContract, } from '../../../../task_manager/server'; import { TelemetryReceiver } from './receiver'; import { allowlistEventFields, copyAllowlistedFields } from './filters'; -import { DiagnosticTask, EndpointTask, ExceptionListsTask, DetectionRulesTask } from './tasks'; +import { createTelemetryTaskConfigs } from './tasks'; import { createUsageCounterLabel } from './helpers'; import { TelemetryEvent } from './types'; import { TELEMETRY_MAX_BUFFER_SIZE } from './constants'; +import { SecurityTelemetryTask, SecurityTelemetryTaskConfig } from './task'; const usageLabelPrefix: string[] = ['security_telemetry', 'sender']; @@ -39,10 +41,7 @@ export class TelemetryEventsSender { private isOptedIn?: boolean = true; // Assume true until the first check private telemetryUsageCounter?: UsageCounter; - private diagnosticTask?: DiagnosticTask; - private endpointTask?: EndpointTask; - private exceptionListsTask?: ExceptionListsTask; - private detectionRulesTask?: DetectionRulesTask; + private telemetryTasks?: SecurityTelemetryTask[]; constructor(logger: Logger) { this.logger = logger.get('telemetry_events'); @@ -58,19 +57,12 @@ export class TelemetryEventsSender { this.telemetryUsageCounter = telemetryUsageCounter; if (taskManager) { - this.diagnosticTask = new DiagnosticTask(this.logger, taskManager, this, telemetryReceiver); - this.endpointTask = new EndpointTask(this.logger, taskManager, this, telemetryReceiver); - this.detectionRulesTask = new DetectionRulesTask( - this.logger, - taskManager, - this, - telemetryReceiver - ); - this.exceptionListsTask = new ExceptionListsTask( - this.logger, - taskManager, - this, - telemetryReceiver + this.telemetryTasks = createTelemetryTaskConfigs().map( + (config: SecurityTelemetryTaskConfig) => { + const task = new SecurityTelemetryTask(config, this.logger, this, telemetryReceiver); + task.register(taskManager); + return task; + } ); } } @@ -83,12 +75,9 @@ export class TelemetryEventsSender { this.telemetryStart = telemetryStart; this.receiver = receiver; - if (taskManager && this.diagnosticTask && this.endpointTask && this.exceptionListsTask) { - this.logger.debug(`starting security telemetry tasks`); - this.diagnosticTask.start(taskManager); - this.endpointTask.start(taskManager); - this.detectionRulesTask?.start(taskManager); - this.exceptionListsTask?.start(taskManager); + if (taskManager && this.telemetryTasks) { + this.logger.debug(`Starting security telemetry tasks`); + this.telemetryTasks.forEach((task) => task.start(taskManager)); } this.logger.debug(`Starting local task`); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/task.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/task.test.ts new file mode 100644 index 0000000000000..aa695b92c1455 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/telemetry/task.test.ts @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { loggingSystemMock } from 'src/core/server/mocks'; +import { taskManagerMock } from '../../../../task_manager/server/mocks'; +import { SuccessfulRunResult } from '../../../../task_manager/server/task'; +import { SecurityTelemetryTask } from './task'; +import { + createMockTaskInstance, + createMockTelemetryEventsSender, + createMockTelemetryReceiver, + createMockSecurityTelemetryTask, +} from './__mocks__'; + +describe('test security telemetry task', () => { + let logger: ReturnType<typeof loggingSystemMock.createLogger>; + + beforeEach(() => { + logger = loggingSystemMock.createLogger(); + }); + + test('telemetry task should be constructed', () => { + const telemetryTask = new SecurityTelemetryTask( + createMockSecurityTelemetryTask(), + logger, + createMockTelemetryEventsSender(true), + createMockTelemetryReceiver() + ); + + expect(telemetryTask).toBeInstanceOf(SecurityTelemetryTask); + }); + + test('telemetry task should be registered and scheduled', async () => { + const mockTaskManagerSetup = taskManagerMock.createSetup(); + const mockTaskManagerStart = taskManagerMock.createStart(); + const telemetryTask = new SecurityTelemetryTask( + createMockSecurityTelemetryTask(), + logger, + createMockTelemetryEventsSender(true), + createMockTelemetryReceiver() + ); + telemetryTask.register(mockTaskManagerSetup); + await telemetryTask.start(mockTaskManagerStart); + + expect(mockTaskManagerSetup.registerTaskDefinitions).toHaveBeenCalled(); + expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); + }); + + test('telemetry task should run if opted in', async () => { + const { + testLastTimestamp, + testResult, + telemetryTask, + mockTelemetryTaskConfig, + mockTelemetryEventsSender, + mockTelemetryReceiver, + } = await testTelemetryTaskRun(true); + + expect(mockTelemetryTaskConfig.runTask).toHaveBeenCalledWith( + telemetryTask.getTaskId(), + logger, + mockTelemetryReceiver, + mockTelemetryEventsSender, + { + last: testLastTimestamp, + current: testResult.state.lastExecutionTimestamp, + } + ); + }); + + test('telemetry task should not run if opted out', async () => { + const { mockTelemetryTaskConfig } = await testTelemetryTaskRun(false); + + expect(mockTelemetryTaskConfig.runTask).not.toHaveBeenCalled(); + }); + + async function testTelemetryTaskRun(optedIn: boolean) { + const now = new Date(); + const testType = 'security:test-task'; + const testLastTimestamp = now.toISOString(); + const mockTaskManagerSetup = taskManagerMock.createSetup(); + const mockTelemetryTaskConfig = createMockSecurityTelemetryTask(testType, testLastTimestamp); + const mockTelemetryEventsSender = createMockTelemetryEventsSender(optedIn); + const mockTelemetryReceiver = createMockTelemetryReceiver(); + const telemetryTask = new SecurityTelemetryTask( + mockTelemetryTaskConfig, + logger, + mockTelemetryEventsSender, + mockTelemetryReceiver + ); + const mockTaskInstance = createMockTaskInstance(telemetryTask.getTaskId(), testType); + + telemetryTask.register(mockTaskManagerSetup); + expect(mockTaskManagerSetup.registerTaskDefinitions).toHaveBeenCalled(); + + const createTaskRunner = + mockTaskManagerSetup.registerTaskDefinitions.mock.calls[0][0][testType].createTaskRunner; + + const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); + const testResult = (await taskRunner.run()) as SuccessfulRunResult; + + expect(mockTelemetryTaskConfig.getLastExecutionTime).toHaveBeenCalled(); + expect(mockTelemetryEventsSender.isTelemetryOptedIn).toHaveBeenCalled(); + + expect(testResult).not.toBeNull(); + expect(testResult).toHaveProperty('state.lastExecutionTimestamp'); + + return { + testLastTimestamp, + testResult, + telemetryTask, + mockTelemetryTaskConfig, + mockTelemetryEventsSender, + mockTelemetryReceiver, + }; + } +}); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/task.ts b/x-pack/plugins/security_solution/server/lib/telemetry/task.ts new file mode 100644 index 0000000000000..15ae5cdb39e50 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/telemetry/task.ts @@ -0,0 +1,148 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import moment from 'moment'; +import { Logger } from 'src/core/server'; +import { + ConcreteTaskInstance, + TaskManagerSetupContract, + TaskManagerStartContract, +} from '../../../../task_manager/server'; +import { TelemetryReceiver } from './receiver'; +import { TelemetryEventsSender } from './sender'; + +export interface SecurityTelemetryTaskConfig { + type: string; + title: string; + interval: string; + timeout: string; + version: string; + getLastExecutionTime?: LastExecutionTimestampCalculator; + runTask: SecurityTelemetryTaskRunner; +} + +export type SecurityTelemetryTaskRunner = ( + taskId: string, + logger: Logger, + receiver: TelemetryReceiver, + sender: TelemetryEventsSender, + taskExecutionPeriod: TaskExecutionPeriod +) => Promise<number>; + +export interface TaskExecutionPeriod { + last?: string; + current: string; +} + +export type LastExecutionTimestampCalculator = ( + executeTo: string, + lastExecutionTimestamp?: string +) => string; + +export class SecurityTelemetryTask { + private readonly config: SecurityTelemetryTaskConfig; + private readonly logger: Logger; + private readonly sender: TelemetryEventsSender; + private readonly receiver: TelemetryReceiver; + + constructor( + config: SecurityTelemetryTaskConfig, + logger: Logger, + sender: TelemetryEventsSender, + receiver: TelemetryReceiver + ) { + this.config = config; + this.logger = logger; + this.sender = sender; + this.receiver = receiver; + } + + public getLastExecutionTime = ( + taskExecutionTime: string, + taskInstance: ConcreteTaskInstance + ): string | undefined => { + return this.config.getLastExecutionTime + ? this.config.getLastExecutionTime( + taskExecutionTime, + taskInstance.state?.lastExecutionTimestamp + ) + : undefined; + }; + + public getTaskId = (): string => { + return `${this.config.type}:${this.config.version}`; + }; + + public register = (taskManager: TaskManagerSetupContract) => { + taskManager.registerTaskDefinitions({ + [this.config.type]: { + title: this.config.title, + timeout: this.config.timeout, + createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { + const { state } = taskInstance; + + return { + run: async () => { + const taskExecutionTime = moment().utc().toISOString(); + const executionPeriod = { + last: this.getLastExecutionTime(taskExecutionTime, taskInstance), + current: taskExecutionTime, + }; + + const hits = await this.runTask(taskInstance.id, executionPeriod); + + return { + state: { + lastExecutionTimestamp: taskExecutionTime, + runs: (state.runs || 0) + 1, + hits, + }, + }; + }, + cancel: async () => {}, + }; + }, + }, + }); + }; + + public start = async (taskManager: TaskManagerStartContract) => { + const taskId = this.getTaskId(); + this.logger.debug(`[task ${taskId}]: attempting to schedule`); + try { + await taskManager.ensureScheduled({ + id: taskId, + taskType: this.config.type, + scope: ['securitySolution'], + schedule: { + interval: this.config.interval, + }, + state: { runs: 0 }, + params: { version: this.config.version }, + }); + } catch (e) { + this.logger.error(`[task ${taskId}]: error scheduling task, received ${e.message}`); + } + }; + + public runTask = async (taskId: string, executionPeriod: TaskExecutionPeriod) => { + this.logger.debug(`[task ${taskId}]: attempting to run`); + if (taskId !== this.getTaskId()) { + this.logger.debug(`[task ${taskId}]: outdated task`); + return 0; + } + + const isOptedIn = await this.sender.isTelemetryOptedIn(); + if (!isOptedIn) { + this.logger.debug(`[task ${taskId}]: telemetry is not opted-in`); + return 0; + } + + this.logger.debug(`[task ${taskId}]: running task`); + return this.config.runTask(taskId, this.logger, this.receiver, this.sender, executionPeriod); + }; +} diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.test.ts index 0a05afb8a6535..5b0c2e334cec9 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.test.ts @@ -6,122 +6,33 @@ */ import { loggingSystemMock } from 'src/core/server/mocks'; -import { taskManagerMock } from '../../../../../task_manager/server/mocks'; -import { TaskStatus } from '../../../../../task_manager/server'; -import { - TelemetryDetectionRulesTask, - TelemetryDetectionRuleListsTaskConstants, -} from './detection_rule'; -import { - createMockTelemetryEventsSender, - MockDetectionRuleListsTask, - createMockTelemetryReceiver, -} from '../mocks'; +import { createTelemetryDetectionRuleListsTaskConfig } from './detection_rule'; +import { createMockTelemetryEventsSender, createMockTelemetryReceiver } from '../__mocks__'; -describe('test detection rule exception lists telemetry', () => { +describe('security detection rule task test', () => { let logger: ReturnType<typeof loggingSystemMock.createLogger>; beforeEach(() => { logger = loggingSystemMock.createLogger(); }); - describe('basic telemetry sanity checks', () => { - test('detection rule lists task can register', () => { - const telemetryDiagTask = new TelemetryDetectionRulesTask( - logger, - taskManagerMock.createSetup(), - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - expect(telemetryDiagTask).toBeInstanceOf(TelemetryDetectionRulesTask); - }); - }); - - test('detection rule task should be registered', () => { - const mockTaskManager = taskManagerMock.createSetup(); - new TelemetryDetectionRulesTask( - logger, - mockTaskManager, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalled(); - }); - - test('detection rule task should be scheduled', async () => { - const mockTaskManagerSetup = taskManagerMock.createSetup(); - const telemetryDiagTask = new TelemetryDetectionRulesTask( - logger, - mockTaskManagerSetup, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - const mockTaskManagerStart = taskManagerMock.createStart(); - await telemetryDiagTask.start(mockTaskManagerStart); - expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); - }); + test('security detecttion rule task should fetch security list data', async () => { + const testTaskExecutionPeriod = { + last: undefined, + current: new Date().toISOString(), + }; + const mockTelemetryEventsSender = createMockTelemetryEventsSender(); + const mockTelemetryReceiver = createMockTelemetryReceiver(); + const telemetryDetectionRuleListsTaskConfig = createTelemetryDetectionRuleListsTaskConfig(1); - test('detection rule task should run', async () => { - const mockContext = createMockTelemetryEventsSender(true); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - const telemetryDiagTask = new MockDetectionRuleListsTask( + await telemetryDetectionRuleListsTaskConfig.runTask( + 'test-id', logger, - mockTaskManager, - mockContext, - mockReceiver + mockTelemetryReceiver, + mockTelemetryEventsSender, + testTaskExecutionPeriod ); - const mockTaskInstance = { - id: TelemetryDetectionRuleListsTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetryDetectionRuleListsTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][ - TelemetryDetectionRuleListsTaskConstants.TYPE - ].createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(telemetryDiagTask.runTask).toHaveBeenCalled(); - }); - - test('detection rule task should not query elastic if telemetry is not opted in', async () => { - const mockSender = createMockTelemetryEventsSender(false); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - new MockDetectionRuleListsTask(logger, mockTaskManager, mockSender, mockReceiver); - - const mockTaskInstance = { - id: TelemetryDetectionRuleListsTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetryDetectionRuleListsTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][ - TelemetryDetectionRuleListsTaskConstants.TYPE - ].createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(mockReceiver.fetchDiagnosticAlerts).not.toHaveBeenCalled(); + expect(mockTelemetryReceiver.fetchDetectionRules).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts index a362be187921d..dd4f2b60a44c9 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts @@ -5,145 +5,78 @@ * 2.0. */ -import moment from 'moment'; import { Logger } from 'src/core/server'; -import { - ConcreteTaskInstance, - TaskManagerSetupContract, - TaskManagerStartContract, -} from '../../../../../task_manager/server'; import { LIST_DETECTION_RULE_EXCEPTION, TELEMETRY_CHANNEL_LISTS } from '../constants'; import { batchTelemetryRecords, templateExceptionList } from '../helpers'; import { TelemetryEventsSender } from '../sender'; import { TelemetryReceiver } from '../receiver'; import { ExceptionListItem, RuleSearchResult } from '../types'; +import { TaskExecutionPeriod } from '../task'; + +export function createTelemetryDetectionRuleListsTaskConfig(maxTelemetryBatch: number) { + return { + type: 'security:telemetry-detection-rules', + title: 'Security Solution Detection Rule Lists Telemetry', + interval: '24h', + timeout: '10m', + version: '1.0.0', + runTask: async ( + taskId: string, + logger: Logger, + receiver: TelemetryReceiver, + sender: TelemetryEventsSender, + taskExecutionPeriod: TaskExecutionPeriod + ) => { + // Lists Telemetry: Detection Rules + + const { body: prebuiltRules } = await receiver.fetchDetectionRules(); + + if (!prebuiltRules) { + logger.debug('no prebuilt rules found'); + return 0; + } -export const TelemetryDetectionRuleListsTaskConstants = { - TIMEOUT: '10m', - TYPE: 'security:telemetry-detection-rules', - INTERVAL: '24h', - VERSION: '1.0.0', -}; - -const MAX_TELEMETRY_BATCH = 1_000; - -export class TelemetryDetectionRulesTask { - private readonly logger: Logger; - private readonly sender: TelemetryEventsSender; - private readonly receiver: TelemetryReceiver; - - constructor( - logger: Logger, - taskManager: TaskManagerSetupContract, - sender: TelemetryEventsSender, - receiver: TelemetryReceiver - ) { - this.logger = logger; - this.sender = sender; - this.receiver = receiver; - - taskManager.registerTaskDefinitions({ - [TelemetryDetectionRuleListsTaskConstants.TYPE]: { - title: 'Security Solution Detection Rule Lists Telemetry', - timeout: TelemetryDetectionRuleListsTaskConstants.TIMEOUT, - createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { - const { state } = taskInstance; - - return { - run: async () => { - const taskExecutionTime = moment().utc().toISOString(); - const hits = await this.runTask(taskInstance.id); - - return { - state: { - lastExecutionTimestamp: taskExecutionTime, - runs: (state.runs || 0) + 1, - hits, - }, - }; - }, - cancel: async () => {}, - }; - }, - }, - }); - } - - public start = async (taskManager: TaskManagerStartContract) => { - try { - await taskManager.ensureScheduled({ - id: this.getTaskId(), - taskType: TelemetryDetectionRuleListsTaskConstants.TYPE, - scope: ['securitySolution'], - schedule: { - interval: TelemetryDetectionRuleListsTaskConstants.INTERVAL, - }, - state: { runs: 0 }, - params: { version: TelemetryDetectionRuleListsTaskConstants.VERSION }, - }); - } catch (e) { - this.logger.error(`Error scheduling task, received ${e.message}`); - } - }; - - private getTaskId = (): string => { - return `${TelemetryDetectionRuleListsTaskConstants.TYPE}:${TelemetryDetectionRuleListsTaskConstants.VERSION}`; - }; - - public runTask = async (taskId: string) => { - if (taskId !== this.getTaskId()) { - return 0; - } - - const isOptedIn = await this.sender.isTelemetryOptedIn(); - if (!isOptedIn) { - return 0; - } - - // Lists Telemetry: Detection Rules - - const { body: prebuiltRules } = await this.receiver.fetchDetectionRules(); + const cacheArray = prebuiltRules.hits.hits.reduce((cache, searchHit) => { + const rule = searchHit._source as RuleSearchResult; + const ruleId = rule.alert.params.ruleId; - const cacheArray = prebuiltRules.hits.hits.reduce((cache, searchHit) => { - const rule = searchHit._source as RuleSearchResult; - const ruleId = rule.alert.params.ruleId; + const shouldNotProcess = + rule === null || + rule === undefined || + ruleId === null || + ruleId === undefined || + searchHit._source?.alert.params.exceptionsList.length === 0; - const shouldNotProcess = - rule === null || - rule === undefined || - ruleId === null || - ruleId === undefined || - searchHit._source?.alert.params.exceptionsList.length === 0; + if (shouldNotProcess) { + return cache; + } - if (shouldNotProcess) { + cache.push(rule); return cache; - } + }, [] as RuleSearchResult[]); - cache.push(rule); - return cache; - }, [] as RuleSearchResult[]); + const detectionRuleExceptions = [] as ExceptionListItem[]; + for (const item of cacheArray) { + const ruleVersion = item.alert.params.version; - const detectionRuleExceptions = [] as ExceptionListItem[]; - for (const item of cacheArray) { - const ruleVersion = item.alert.params.version; - - for (const ex of item.alert.params.exceptionsList) { - const listItem = await this.receiver.fetchDetectionExceptionList(ex.list_id, ruleVersion); - for (const exceptionItem of listItem.data) { - detectionRuleExceptions.push(exceptionItem); + for (const ex of item.alert.params.exceptionsList) { + const listItem = await receiver.fetchDetectionExceptionList(ex.list_id, ruleVersion); + for (const exceptionItem of listItem.data) { + detectionRuleExceptions.push(exceptionItem); + } } } - } - const detectionRuleExceptionsJson = templateExceptionList( - detectionRuleExceptions, - LIST_DETECTION_RULE_EXCEPTION - ); + const detectionRuleExceptionsJson = templateExceptionList( + detectionRuleExceptions, + LIST_DETECTION_RULE_EXCEPTION + ); - batchTelemetryRecords(detectionRuleExceptionsJson, MAX_TELEMETRY_BATCH).forEach((batch) => { - this.sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); - }); + batchTelemetryRecords(detectionRuleExceptionsJson, maxTelemetryBatch).forEach((batch) => { + sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + }); - return detectionRuleExceptions.length; + return detectionRuleExceptions.length; + }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts index fdf48bd99b3b2..579ec42b1ec32 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts @@ -6,117 +6,45 @@ */ import { loggingSystemMock } from 'src/core/server/mocks'; -import { taskManagerMock } from '../../../../../task_manager/server/mocks'; -import { TaskStatus } from '../../../../../task_manager/server'; -import { TelemetryDiagTask, TelemetryDiagTaskConstants } from './diagnostic'; -import { - createMockTelemetryEventsSender, - MockTelemetryDiagnosticTask, - createMockTelemetryReceiver, -} from '../mocks'; +import { createTelemetryDiagnosticsTaskConfig } from './diagnostic'; +import { createMockTelemetryEventsSender, createMockTelemetryReceiver } from '../__mocks__'; -describe('test', () => { +describe('diagnostics telemetry task test', () => { let logger: ReturnType<typeof loggingSystemMock.createLogger>; beforeEach(() => { logger = loggingSystemMock.createLogger(); }); - describe('basic diagnostic alert telemetry sanity checks', () => { - test('diagnostic task can register', () => { - const telemetryDiagTask = new TelemetryDiagTask( - logger, - taskManagerMock.createSetup(), - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - expect(telemetryDiagTask).toBeInstanceOf(TelemetryDiagTask); - }); - }); + test('diagnostics telemetry task should query and enqueue events', async () => { + const testAlertDoc1 = { id: 'test1' }; + const testAlertDoc2 = { id: 'test2' }; + const testDiagnosticsAlerts = { + hits: { hits: [{ _source: [testAlertDoc1] }, { _source: [testAlertDoc2] }] }, + }; + const testTaskExecutionPeriod = { + last: new Date().toISOString(), + current: new Date().toISOString(), + }; + const mockTelemetryEventsSender = createMockTelemetryEventsSender(); + const mockTelemetryReceiver = createMockTelemetryReceiver(testDiagnosticsAlerts); + const telemetryDiagnoticsTaskConfig = createTelemetryDiagnosticsTaskConfig(); - test('diagnostic task should be registered', () => { - const mockTaskManager = taskManagerMock.createSetup(); - new TelemetryDiagTask( + await telemetryDiagnoticsTaskConfig.runTask( + 'test-id', logger, - mockTaskManager, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() + mockTelemetryReceiver, + mockTelemetryEventsSender, + testTaskExecutionPeriod ); - expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalled(); - }); - - test('diagnostic task should be scheduled', async () => { - const mockTaskManagerSetup = taskManagerMock.createSetup(); - const telemetryDiagTask = new TelemetryDiagTask( - logger, - mockTaskManagerSetup, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() + expect(mockTelemetryReceiver.fetchDiagnosticAlerts).toHaveBeenCalledWith( + testTaskExecutionPeriod.last, + testTaskExecutionPeriod.current ); - const mockTaskManagerStart = taskManagerMock.createStart(); - await telemetryDiagTask.start(mockTaskManagerStart); - expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); - }); - - test('diagnostic task should run', async () => { - const mockContext = createMockTelemetryEventsSender(true); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - const telemetryDiagTask = new MockTelemetryDiagnosticTask( - logger, - mockTaskManager, - mockContext, - mockReceiver + expect(mockTelemetryEventsSender.queueTelemetryEvents).toHaveBeenCalledWith( + testDiagnosticsAlerts.hits.hits.flatMap((doc) => [doc._source]) ); - - const mockTaskInstance = { - id: TelemetryDiagTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetryDiagTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][TelemetryDiagTaskConstants.TYPE] - .createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(telemetryDiagTask.runTask).toHaveBeenCalled(); - }); - - test('diagnostic task should not query elastic if telemetry is not opted in', async () => { - const mockSender = createMockTelemetryEventsSender(false); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - new MockTelemetryDiagnosticTask(logger, mockTaskManager, mockSender, mockReceiver); - - const mockTaskInstance = { - id: TelemetryDiagTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetryDiagTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][TelemetryDiagTaskConstants.TYPE] - .createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(mockReceiver.fetchDiagnosticAlerts).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts index 77d5ff72b04cb..fba96da63ecaf 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts @@ -5,118 +5,49 @@ * 2.0. */ -import moment from 'moment'; import { Logger } from 'src/core/server'; -import { - ConcreteTaskInstance, - TaskManagerSetupContract, - TaskManagerStartContract, -} from '../../../../../task_manager/server'; import { getPreviousDiagTaskTimestamp } from '../helpers'; import { TelemetryEventsSender } from '../sender'; import { TelemetryEvent } from '../types'; import { TelemetryReceiver } from '../receiver'; - -export const TelemetryDiagTaskConstants = { - TIMEOUT: '1m', - TYPE: 'security:endpoint-diagnostics', - INTERVAL: '5m', - VERSION: '1.0.0', -}; - -export class TelemetryDiagTask { - private readonly logger: Logger; - private readonly sender: TelemetryEventsSender; - private readonly receiver: TelemetryReceiver; - - constructor( - logger: Logger, - taskManager: TaskManagerSetupContract, - sender: TelemetryEventsSender, - receiver: TelemetryReceiver - ) { - this.logger = logger; - this.sender = sender; - this.receiver = receiver; - - taskManager.registerTaskDefinitions({ - [TelemetryDiagTaskConstants.TYPE]: { - title: 'Security Solution Telemetry Diagnostics task', - timeout: TelemetryDiagTaskConstants.TIMEOUT, - createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { - const { state } = taskInstance; - - return { - run: async () => { - const executeTo = moment().utc().toISOString(); - const executeFrom = getPreviousDiagTaskTimestamp( - executeTo, - taskInstance.state?.lastExecutionTimestamp - ); - const hits = await this.runTask(taskInstance.id, executeFrom, executeTo); - - return { - state: { - lastExecutionTimestamp: executeTo, - lastDiagAlertCount: hits, - runs: (state.runs || 0) + 1, - }, - }; - }, - cancel: async () => {}, - }; - }, - }, - }); - } - - public start = async (taskManager: TaskManagerStartContract) => { - try { - await taskManager.ensureScheduled({ - id: this.getTaskId(), - taskType: TelemetryDiagTaskConstants.TYPE, - scope: ['securitySolution'], - schedule: { - interval: TelemetryDiagTaskConstants.INTERVAL, - }, - state: { runs: 0 }, - params: { version: TelemetryDiagTaskConstants.VERSION }, - }); - } catch (e) { - this.logger.error(`Error scheduling task, received ${e.message}`); - } - }; - - private getTaskId = (): string => { - return `${TelemetryDiagTaskConstants.TYPE}:${TelemetryDiagTaskConstants.VERSION}`; - }; - - public runTask = async (taskId: string, searchFrom: string, searchTo: string) => { - this.logger.debug(`Running task ${taskId}`); - if (taskId !== this.getTaskId()) { - this.logger.debug(`Outdated task running: ${taskId}`); - return 0; - } - - const isOptedIn = await this.sender.isTelemetryOptedIn(); - if (!isOptedIn) { - this.logger.debug(`Telemetry is not opted-in.`); - return 0; - } - - const response = await this.receiver.fetchDiagnosticAlerts(searchFrom, searchTo); - - const hits = response.hits?.hits || []; - if (!Array.isArray(hits) || !hits.length) { - this.logger.debug('no diagnostic alerts retrieved'); - return 0; - } - this.logger.debug(`Received ${hits.length} diagnostic alerts`); - - const diagAlerts: TelemetryEvent[] = hits.flatMap((h) => - h._source != null ? [h._source] : [] - ); - this.sender.queueTelemetryEvents(diagAlerts); - return diagAlerts.length; +import { TaskExecutionPeriod } from '../task'; + +export function createTelemetryDiagnosticsTaskConfig() { + return { + type: 'security:endpoint-diagnostics', + title: 'Security Solution Telemetry Diagnostics task', + interval: '5m', + timeout: '1m', + version: '1.0.0', + getLastExecutionTime: getPreviousDiagTaskTimestamp, + runTask: async ( + taskId: string, + logger: Logger, + receiver: TelemetryReceiver, + sender: TelemetryEventsSender, + taskExecutionPeriod: TaskExecutionPeriod + ) => { + if (!taskExecutionPeriod.last) { + throw new Error('last execution timestamp is required'); + } + + const response = await receiver.fetchDiagnosticAlerts( + taskExecutionPeriod.last, + taskExecutionPeriod.current + ); + + const hits = response.hits?.hits || []; + if (!Array.isArray(hits) || !hits.length) { + logger.debug('no diagnostic alerts retrieved'); + return 0; + } + logger.debug(`Received ${hits.length} diagnostic alerts`); + + const diagAlerts: TelemetryEvent[] = hits.flatMap((h) => + h._source != null ? [h._source] : [] + ); + sender.queueTelemetryEvents(diagAlerts); + return diagAlerts.length; + }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.test.ts index 85f501d86f9c1..16c10a90109b2 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.test.ts @@ -6,119 +6,41 @@ */ import { loggingSystemMock } from 'src/core/server/mocks'; -import { TaskStatus } from '../../../../../task_manager/server'; -import { taskManagerMock } from '../../../../../task_manager/server/mocks'; +import { createTelemetryEndpointTaskConfig } from './endpoint'; +import { createMockTelemetryEventsSender, createMockTelemetryReceiver } from '../__mocks__'; -import { TelemetryEndpointTask, TelemetryEndpointTaskConstants } from './endpoint'; -import { - createMockTelemetryEventsSender, - MockTelemetryEndpointTask, - createMockTelemetryReceiver, -} from '../mocks'; - -describe('test', () => { +describe('endpoint telemetry task test', () => { let logger: ReturnType<typeof loggingSystemMock.createLogger>; beforeEach(() => { logger = loggingSystemMock.createLogger(); }); - describe('endpoint alert telemetry checks', () => { - test('the endpoint task can register', () => { - const telemetryEndpointTask = new TelemetryEndpointTask( - logger, - taskManagerMock.createSetup(), - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - expect(telemetryEndpointTask).toBeInstanceOf(TelemetryEndpointTask); - }); - }); + test('endpoint telemetry task should fetch endpoint data', async () => { + const testTaskExecutionPeriod = { + last: new Date().toISOString(), + current: new Date().toISOString(), + }; + const mockTelemetryEventsSender = createMockTelemetryEventsSender(); + const mockTelemetryReceiver = createMockTelemetryReceiver(); + const telemetryEndpointTaskConfig = createTelemetryEndpointTaskConfig(1); - test('the endpoint task should be registered', () => { - const mockTaskManager = taskManagerMock.createSetup(); - new TelemetryEndpointTask( + await telemetryEndpointTaskConfig.runTask( + 'test-id', logger, - mockTaskManager, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() + mockTelemetryReceiver, + mockTelemetryEventsSender, + testTaskExecutionPeriod ); - expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalled(); - }); - - test('the endpoint task should be scheduled', async () => { - const mockTaskManagerSetup = taskManagerMock.createSetup(); - const telemetryEndpointTask = new TelemetryEndpointTask( - logger, - mockTaskManagerSetup, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() + expect(mockTelemetryReceiver.fetchFleetAgents).toHaveBeenCalled(); + expect(mockTelemetryReceiver.fetchEndpointMetrics).toHaveBeenCalledWith( + testTaskExecutionPeriod.last, + testTaskExecutionPeriod.current ); - - const mockTaskManagerStart = taskManagerMock.createStart(); - await telemetryEndpointTask.start(mockTaskManagerStart); - expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); - }); - - test('endpoint task should not query elastic if telemetry is not opted in', async () => { - const mockSender = createMockTelemetryEventsSender(false); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - new MockTelemetryEndpointTask(logger, mockTaskManager, mockSender, mockReceiver); - - const mockTaskInstance = { - id: TelemetryEndpointTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetryEndpointTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][TelemetryEndpointTaskConstants.TYPE] - .createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(mockReceiver.fetchEndpointMetrics).not.toHaveBeenCalled(); - expect(mockReceiver.fetchEndpointPolicyResponses).not.toHaveBeenCalled(); - }); - - test('endpoint task should run when opted in', async () => { - const mockSender = createMockTelemetryEventsSender(true); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - const telemetryEpMetaTask = new MockTelemetryEndpointTask( - logger, - mockTaskManager, - mockSender, - mockReceiver + expect(mockTelemetryReceiver.fetchEndpointPolicyResponses).toHaveBeenCalledWith( + testTaskExecutionPeriod.last, + testTaskExecutionPeriod.current ); - - const mockTaskInstance = { - id: TelemetryEndpointTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetryEndpointTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][TelemetryEndpointTaskConstants.TYPE] - .createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(telemetryEpMetaTask.runTask).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts index c6bf4b06e70f0..a06aac19d313b 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts @@ -5,35 +5,23 @@ * 2.0. */ -import moment from 'moment'; import { Logger } from 'src/core/server'; +import { TelemetryEventsSender } from '../sender'; import { - ConcreteTaskInstance, - TaskManagerSetupContract, - TaskManagerStartContract, -} from '../../../../../task_manager/server'; + EndpointMetricsAggregation, + EndpointPolicyResponseAggregation, + EndpointPolicyResponseDocument, +} from '../types'; +import { TelemetryReceiver } from '../receiver'; +import { TaskExecutionPeriod } from '../task'; import { batchTelemetryRecords, getPreviousDailyTaskTimestamp, isPackagePolicyList, } from '../helpers'; -import { TelemetryEventsSender } from '../sender'; import { PolicyData } from '../../../../common/endpoint/types'; import { FLEET_ENDPOINT_PACKAGE } from '../../../../../fleet/common'; -import { - EndpointMetricsAggregation, - EndpointPolicyResponseAggregation, - EndpointPolicyResponseDocument, -} from '../types'; import { TELEMETRY_CHANNEL_ENDPOINT_META } from '../constants'; -import { TelemetryReceiver } from '../receiver'; - -export const TelemetryEndpointTaskConstants = { - TIMEOUT: '5m', - TYPE: 'security:endpoint-meta-telemetry', - INTERVAL: '24h', - VERSION: '1.0.0', -}; // Endpoint agent uses this Policy ID while it's installing. const DefaultEndpointPolicyIdToIgnore = '00000000-0000-0000-0000-000000000000'; @@ -45,295 +33,236 @@ const EmptyFleetAgentResponse = { perPage: 0, }; -/** Telemetry Endpoint Task - * - * The Endpoint Telemetry task is a daily batch job that collects and transmits non-sensitive - * endpoint performance and policy logs to Elastic Security Data Engineering. It is used to - * identify bugs or common UX issues with the Elastic Security Endpoint agent. - */ -export class TelemetryEndpointTask { - private readonly logger: Logger; - private readonly sender: TelemetryEventsSender; - private readonly receiver: TelemetryReceiver; +export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { + return { + type: 'security:endpoint-meta-telemetry', + title: 'Security Solution Telemetry Endpoint Metrics and Info task', + interval: '24h', + timeout: '5m', + version: '1.0.0', + getLastExecutionTime: getPreviousDailyTaskTimestamp, + runTask: async ( + taskId: string, + logger: Logger, + receiver: TelemetryReceiver, + sender: TelemetryEventsSender, + taskExecutionPeriod: TaskExecutionPeriod + ) => { + if (!taskExecutionPeriod.last) { + throw new Error('last execution timestamp is required'); + } - constructor( - logger: Logger, - taskManager: TaskManagerSetupContract, - sender: TelemetryEventsSender, - receiver: TelemetryReceiver - ) { - this.logger = logger; - this.sender = sender; - this.receiver = receiver; + const endpointData = await fetchEndpointData( + receiver, + taskExecutionPeriod.last, + taskExecutionPeriod.current + ); - taskManager.registerTaskDefinitions({ - [TelemetryEndpointTaskConstants.TYPE]: { - title: 'Security Solution Telemetry Endpoint Metrics and Info task', - timeout: TelemetryEndpointTaskConstants.TIMEOUT, - createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { - const { state } = taskInstance; + /** STAGE 1 - Fetch Endpoint Agent Metrics + * + * Reads Endpoint Agent metrics out of the `.ds-metrics-endpoint.metrics` data stream + * and buckets them by Endpoint Agent id and sorts by the top hit. The EP agent will + * report its metrics once per day OR every time a policy change has occured. If + * a metric document(s) exists for an EP agent we map to fleet agent and policy + */ + if (endpointData.endpointMetrics === undefined) { + logger.debug(`no endpoint metrics to report`); + return 0; + } - return { - run: async () => { - const taskExecutionTime = moment().utc().toISOString(); - const lastExecutionTimestamp = getPreviousDailyTaskTimestamp( - taskExecutionTime, - taskInstance.state?.lastExecutionTimestamp - ); + const { body: endpointMetricsResponse } = endpointData.endpointMetrics as unknown as { + body: EndpointMetricsAggregation; + }; - const hits = await this.runTask( - taskInstance.id, - lastExecutionTimestamp, - taskExecutionTime - ); + if (endpointMetricsResponse.aggregations === undefined) { + logger.debug(`no endpoint metrics to report`); + return 0; + } - return { - state: { - lastExecutionTimestamp: taskExecutionTime, - runs: (state.runs || 0) + 1, - hits, - }, - }; - }, - cancel: async () => {}, + const endpointMetrics = endpointMetricsResponse.aggregations.endpoint_agents.buckets.map( + (epMetrics) => { + return { + endpoint_agent: epMetrics.latest_metrics.hits.hits[0]._source.agent.id, + endpoint_version: epMetrics.latest_metrics.hits.hits[0]._source.agent.version, + endpoint_metrics: epMetrics.latest_metrics.hits.hits[0]._source, }; - }, - }, - }); - } - - public start = async (taskManager: TaskManagerStartContract) => { - try { - await taskManager.ensureScheduled({ - id: this.getTaskId(), - taskType: TelemetryEndpointTaskConstants.TYPE, - scope: ['securitySolution'], - schedule: { - interval: TelemetryEndpointTaskConstants.INTERVAL, - }, - state: { runs: 0 }, - params: { version: TelemetryEndpointTaskConstants.VERSION }, - }); - } catch (e) { - this.logger.error(`Error scheduling task, received ${e.message}`); - } - }; - - private getTaskId = (): string => { - return `${TelemetryEndpointTaskConstants.TYPE}:${TelemetryEndpointTaskConstants.VERSION}`; - }; - - private async fetchEndpointData(executeFrom: string, executeTo: string) { - const [fleetAgentsResponse, epMetricsResponse, policyResponse] = await Promise.allSettled([ - this.receiver.fetchFleetAgents(), - this.receiver.fetchEndpointMetrics(executeFrom, executeTo), - this.receiver.fetchEndpointPolicyResponses(executeFrom, executeTo), - ]); - - return { - fleetAgentsResponse: - fleetAgentsResponse.status === 'fulfilled' - ? fleetAgentsResponse.value - : EmptyFleetAgentResponse, - endpointMetrics: - epMetricsResponse.status === 'fulfilled' ? epMetricsResponse.value : undefined, - epPolicyResponse: policyResponse.status === 'fulfilled' ? policyResponse.value : undefined, - }; - } - - public runTask = async (taskId: string, executeFrom: string, executeTo: string) => { - if (taskId !== this.getTaskId()) { - this.logger.debug(`Outdated task running: ${taskId}`); - return 0; - } - - const isOptedIn = await this.sender.isTelemetryOptedIn(); - if (!isOptedIn) { - this.logger.debug(`Telemetry is not opted-in.`); - return 0; - } - - const endpointData = await this.fetchEndpointData(executeFrom, executeTo); - - /** STAGE 1 - Fetch Endpoint Agent Metrics - * - * Reads Endpoint Agent metrics out of the `.ds-metrics-endpoint.metrics` data stream - * and buckets them by Endpoint Agent id and sorts by the top hit. The EP agent will - * report its metrics once per day OR every time a policy change has occured. If - * a metric document(s) exists for an EP agent we map to fleet agent and policy - */ - if (endpointData.endpointMetrics === undefined) { - this.logger.debug(`no endpoint metrics to report`); - return 0; - } - - const { body: endpointMetricsResponse } = endpointData.endpointMetrics as unknown as { - body: EndpointMetricsAggregation; - }; + } + ); - if (endpointMetricsResponse.aggregations === undefined) { - this.logger.debug(`no endpoint metrics to report`); - return 0; - } + /** STAGE 2 - Fetch Fleet Agent Config + * + * As the policy id + policy version does not exist on the Endpoint Metrics document + * we need to fetch information about the Fleet Agent and sync the metrics document + * with the Agent's policy data. + * + */ + const agentsResponse = endpointData.fleetAgentsResponse; - const endpointMetrics = endpointMetricsResponse.aggregations.endpoint_agents.buckets.map( - (epMetrics) => { - return { - endpoint_agent: epMetrics.latest_metrics.hits.hits[0]._source.agent.id, - endpoint_version: epMetrics.latest_metrics.hits.hits[0]._source.agent.version, - endpoint_metrics: epMetrics.latest_metrics.hits.hits[0]._source, - }; + if (agentsResponse === undefined) { + logger.debug('no fleet agent information available'); + return 0; } - ); - /** STAGE 2 - Fetch Fleet Agent Config - * - * As the policy id + policy version does not exist on the Endpoint Metrics document - * we need to fetch information about the Fleet Agent and sync the metrics document - * with the Agent's policy data. - * - */ - const agentsResponse = endpointData.fleetAgentsResponse; + const fleetAgents = agentsResponse.agents.reduce((cache, agent) => { + if (agent.id === DefaultEndpointPolicyIdToIgnore) { + return cache; + } - if (agentsResponse === undefined) { - this.logger.debug('no fleet agent information available'); - return 0; - } + if (agent.policy_id !== null && agent.policy_id !== undefined) { + cache.set(agent.id, agent.policy_id); + } - const fleetAgents = agentsResponse.agents.reduce((cache, agent) => { - if (agent.id === DefaultEndpointPolicyIdToIgnore) { return cache; - } - - if (agent.policy_id !== null && agent.policy_id !== undefined) { - cache.set(agent.id, agent.policy_id); - } - - return cache; - }, new Map<string, string>()); - - const endpointPolicyCache = new Map<string, PolicyData>(); - for (const policyInfo of fleetAgents.values()) { - if (policyInfo !== null && policyInfo !== undefined && !endpointPolicyCache.has(policyInfo)) { - const agentPolicy = await this.receiver.fetchPolicyConfigs(policyInfo); - const packagePolicies = agentPolicy?.package_policies; - - if (packagePolicies !== undefined && isPackagePolicyList(packagePolicies)) { - packagePolicies - .map((pPolicy) => pPolicy as PolicyData) - .forEach((pPolicy) => { - if (pPolicy.inputs[0].config !== undefined) { - pPolicy.inputs.forEach((input) => { - if ( - input.type === FLEET_ENDPOINT_PACKAGE && - input.config !== undefined && - policyInfo !== undefined - ) { - endpointPolicyCache.set(policyInfo, pPolicy); - } - }); - } - }); + }, new Map<string, string>()); + + const endpointPolicyCache = new Map<string, PolicyData>(); + for (const policyInfo of fleetAgents.values()) { + if ( + policyInfo !== null && + policyInfo !== undefined && + !endpointPolicyCache.has(policyInfo) + ) { + const agentPolicy = await receiver.fetchPolicyConfigs(policyInfo); + const packagePolicies = agentPolicy?.package_policies; + + if (packagePolicies !== undefined && isPackagePolicyList(packagePolicies)) { + packagePolicies + .map((pPolicy) => pPolicy as PolicyData) + .forEach((pPolicy) => { + if (pPolicy.inputs[0].config !== undefined) { + pPolicy.inputs.forEach((input) => { + if ( + input.type === FLEET_ENDPOINT_PACKAGE && + input.config !== undefined && + policyInfo !== undefined + ) { + endpointPolicyCache.set(policyInfo, pPolicy); + } + }); + } + }); + } } } - } - /** STAGE 3 - Fetch Endpoint Policy Responses - * - * Reads Endpoint Agent policy responses out of the `.ds-metrics-endpoint.policy*` data - * stream and creates a local K/V structure that stores the policy response (V) with - * the Endpoint Agent Id (K). A value will only exist if there has been a endpoint - * enrolled in the last 24 hours OR a policy change has occurred. We only send - * non-successful responses. If the field is null, we assume no responses in - * the last 24h or no failures/warnings in the policy applied. - * - */ - const { body: failedPolicyResponses } = endpointData.epPolicyResponse as unknown as { - body: EndpointPolicyResponseAggregation; - }; - - // If there is no policy responses in the 24h > now then we will continue - const policyResponses = failedPolicyResponses.aggregations - ? failedPolicyResponses.aggregations.policy_responses.buckets.reduce( - (cache, endpointAgentId) => { - const doc = endpointAgentId.latest_response.hits.hits[0]; - cache.set(endpointAgentId.key, doc); - return cache; - }, - new Map<string, EndpointPolicyResponseDocument>() - ) - : new Map<string, EndpointPolicyResponseDocument>(); + /** STAGE 3 - Fetch Endpoint Policy Responses + * + * Reads Endpoint Agent policy responses out of the `.ds-metrics-endpoint.policy*` data + * stream and creates a local K/V structure that stores the policy response (V) with + * the Endpoint Agent Id (K). A value will only exist if there has been a endpoint + * enrolled in the last 24 hours OR a policy change has occurred. We only send + * non-successful responses. If the field is null, we assume no responses in + * the last 24h or no failures/warnings in the policy applied. + * + */ + const { body: failedPolicyResponses } = endpointData.epPolicyResponse as unknown as { + body: EndpointPolicyResponseAggregation; + }; + + // If there is no policy responses in the 24h > now then we will continue + const policyResponses = failedPolicyResponses.aggregations + ? failedPolicyResponses.aggregations.policy_responses.buckets.reduce( + (cache, endpointAgentId) => { + const doc = endpointAgentId.latest_response.hits.hits[0]; + cache.set(endpointAgentId.key, doc); + return cache; + }, + new Map<string, EndpointPolicyResponseDocument>() + ) + : new Map<string, EndpointPolicyResponseDocument>(); - /** STAGE 4 - Create the telemetry log records - * - * Iterates through the endpoint metrics documents at STAGE 1 and joins them together - * to form the telemetry log that is sent back to Elastic Security developers to - * make improvements to the product. - * - */ - try { - const telemetryPayloads = endpointMetrics.map((endpoint) => { - let policyConfig = null; - let failedPolicy = null; + /** STAGE 4 - Create the telemetry log records + * + * Iterates through the endpoint metrics documents at STAGE 1 and joins them together + * to form the telemetry log that is sent back to Elastic Security developers to + * make improvements to the product. + * + */ + try { + const telemetryPayloads = endpointMetrics.map((endpoint) => { + let policyConfig = null; + let failedPolicy = null; - const fleetAgentId = endpoint.endpoint_metrics.elastic.agent.id; - const endpointAgentId = endpoint.endpoint_agent; + const fleetAgentId = endpoint.endpoint_metrics.elastic.agent.id; + const endpointAgentId = endpoint.endpoint_agent; - const policyInformation = fleetAgents.get(fleetAgentId); - if (policyInformation) { - policyConfig = endpointPolicyCache.get(policyInformation) || null; + const policyInformation = fleetAgents.get(fleetAgentId); + if (policyInformation) { + policyConfig = endpointPolicyCache.get(policyInformation) || null; - if (policyConfig) { - failedPolicy = policyResponses.get(endpointAgentId); + if (policyConfig) { + failedPolicy = policyResponses.get(endpointAgentId); + } } - } - const { cpu, memory, uptime } = endpoint.endpoint_metrics.Endpoint.metrics; + const { cpu, memory, uptime } = endpoint.endpoint_metrics.Endpoint.metrics; - return { - '@timestamp': executeTo, - endpoint_id: endpointAgentId, - endpoint_version: endpoint.endpoint_version, - endpoint_package_version: policyConfig?.package?.version || null, - endpoint_metrics: { - cpu: cpu.endpoint, - memory: memory.endpoint.private, - uptime, - }, - endpoint_meta: { - os: endpoint.endpoint_metrics.host.os, - }, - policy_config: policyConfig !== null ? policyConfig?.inputs[0].config.policy : {}, - policy_response: - failedPolicy !== null && failedPolicy !== undefined - ? { - agent_policy_status: failedPolicy._source.event.agent_id_status, - manifest_version: - failedPolicy._source.Endpoint.policy.applied.artifacts.global.version, - status: failedPolicy._source.Endpoint.policy.applied.status, - actions: failedPolicy._source.Endpoint.policy.applied.actions - .map((action) => (action.status !== 'success' ? action : null)) - .filter((action) => action !== null), - } - : {}, - telemetry_meta: { - metrics_timestamp: endpoint.endpoint_metrics['@timestamp'], - }, - }; - }); + return { + '@timestamp': taskExecutionPeriod.current, + endpoint_id: endpointAgentId, + endpoint_version: endpoint.endpoint_version, + endpoint_package_version: policyConfig?.package?.version || null, + endpoint_metrics: { + cpu: cpu.endpoint, + memory: memory.endpoint.private, + uptime, + }, + endpoint_meta: { + os: endpoint.endpoint_metrics.host.os, + }, + policy_config: policyConfig !== null ? policyConfig?.inputs[0].config.policy : {}, + policy_response: + failedPolicy !== null && failedPolicy !== undefined + ? { + agent_policy_status: failedPolicy._source.event.agent_id_status, + manifest_version: + failedPolicy._source.Endpoint.policy.applied.artifacts.global.version, + status: failedPolicy._source.Endpoint.policy.applied.status, + actions: failedPolicy._source.Endpoint.policy.applied.actions + .map((action) => (action.status !== 'success' ? action : null)) + .filter((action) => action !== null), + } + : {}, + telemetry_meta: { + metrics_timestamp: endpoint.endpoint_metrics['@timestamp'], + }, + }; + }); + + /** + * STAGE 5 - Send the documents + * + * Send the documents in a batches of maxTelemetryBatch + */ + batchTelemetryRecords(telemetryPayloads, maxTelemetryBatch).forEach((telemetryBatch) => + sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, telemetryBatch) + ); + return telemetryPayloads.length; + } catch (err) { + logger.warn('could not complete endpoint alert telemetry task'); + return 0; + } + }, + }; +} - /** - * STAGE 5 - Send the documents - * - * Send the documents in a batches of 100 - */ - batchTelemetryRecords(telemetryPayloads, 100).forEach((telemetryBatch) => - this.sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, telemetryBatch) - ); - return telemetryPayloads.length; - } catch (err) { - this.logger.warn('could not complete endpoint alert telemetry task'); - return 0; - } +async function fetchEndpointData( + receiver: TelemetryReceiver, + executeFrom: string, + executeTo: string +) { + const [fleetAgentsResponse, epMetricsResponse, policyResponse] = await Promise.allSettled([ + receiver.fetchFleetAgents(), + receiver.fetchEndpointMetrics(executeFrom, executeTo), + receiver.fetchEndpointPolicyResponses(executeFrom, executeTo), + ]); + + return { + fleetAgentsResponse: + fleetAgentsResponse.status === 'fulfilled' + ? fleetAgentsResponse.value + : EmptyFleetAgentResponse, + endpointMetrics: epMetricsResponse.status === 'fulfilled' ? epMetricsResponse.value : undefined, + epPolicyResponse: policyResponse.status === 'fulfilled' ? policyResponse.value : undefined, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/index.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/index.ts index a850f848567cb..0b25ef87452f6 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/index.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/index.ts @@ -5,7 +5,22 @@ * 2.0. */ -export { TelemetryDiagTask as DiagnosticTask } from './diagnostic'; -export { TelemetryEndpointTask as EndpointTask } from './endpoint'; -export { TelemetryExceptionListsTask as ExceptionListsTask } from './security_lists'; -export { TelemetryDetectionRulesTask as DetectionRulesTask } from './detection_rule'; +import { SecurityTelemetryTaskConfig } from '../task'; +import { createTelemetryDiagnosticsTaskConfig } from './diagnostic'; +import { createTelemetryEndpointTaskConfig } from './endpoint'; +import { createTelemetrySecurityListTaskConfig } from './security_lists'; +import { createTelemetryDetectionRuleListsTaskConfig } from './detection_rule'; +import { + MAX_SECURITY_LIST_TELEMETRY_BATCH, + MAX_ENDPOINT_TELEMETRY_BATCH, + MAX_DETECTION_RULE_TELEMETRY_BATCH, +} from '../constants'; + +export function createTelemetryTaskConfigs(): SecurityTelemetryTaskConfig[] { + return [ + createTelemetryDiagnosticsTaskConfig(), + createTelemetryEndpointTaskConfig(MAX_SECURITY_LIST_TELEMETRY_BATCH), + createTelemetrySecurityListTaskConfig(MAX_ENDPOINT_TELEMETRY_BATCH), + createTelemetryDetectionRuleListsTaskConfig(MAX_DETECTION_RULE_TELEMETRY_BATCH), + ]; +} diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.test.ts index c54577cb8496e..e4e09d308d4c2 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.test.ts @@ -6,117 +6,41 @@ */ import { loggingSystemMock } from 'src/core/server/mocks'; -import { TaskStatus } from '../../../../../task_manager/server'; -import { taskManagerMock } from '../../../../../task_manager/server/mocks'; -import { TelemetryExceptionListsTask, TelemetrySecuityListsTaskConstants } from './security_lists'; +import { createTelemetrySecurityListTaskConfig } from './security_lists'; +import { createMockTelemetryEventsSender, createMockTelemetryReceiver } from '../__mocks__'; import { - createMockTelemetryEventsSender, - MockExceptionListsTask, - createMockTelemetryReceiver, -} from '../mocks'; + ENDPOINT_LIST_ID, + ENDPOINT_EVENT_FILTERS_LIST_ID, +} from '@kbn/securitysolution-list-constants'; -describe('test exception list telemetry task functionality', () => { +describe('security list telemetry task test', () => { let logger: ReturnType<typeof loggingSystemMock.createLogger>; beforeEach(() => { logger = loggingSystemMock.createLogger(); }); - test('the trusted apps task can register', () => { - const telemetryTrustedAppsTask = new TelemetryExceptionListsTask( - logger, - taskManagerMock.createSetup(), - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - expect(telemetryTrustedAppsTask).toBeInstanceOf(TelemetryExceptionListsTask); - }); - - test('the exception list task should be registered', () => { - const mockTaskManager = taskManagerMock.createSetup(); - new TelemetryExceptionListsTask( - logger, - mockTaskManager, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalled(); - }); - - test('the exception list task should be scheduled', async () => { - const mockTaskManagerSetup = taskManagerMock.createSetup(); - const telemetryTrustedAppsTask = new TelemetryExceptionListsTask( - logger, - mockTaskManagerSetup, - createMockTelemetryEventsSender(true), - createMockTelemetryReceiver() - ); - - const mockTaskManagerStart = taskManagerMock.createStart(); - await telemetryTrustedAppsTask.start(mockTaskManagerStart); - expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); - }); - - test('the exception list task should not query elastic if telemetry is not opted in', async () => { - const mockSender = createMockTelemetryEventsSender(false); - const mockReceiver = createMockTelemetryReceiver(); - const mockTaskManager = taskManagerMock.createSetup(); - new MockExceptionListsTask(logger, mockTaskManager, mockSender, mockReceiver); - - const mockTaskInstance = { - id: TelemetrySecuityListsTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetrySecuityListsTaskConstants.TYPE, + test('security list telemetry task should fetch security list data', async () => { + const testTaskExecutionPeriod = { + last: undefined, + current: new Date().toISOString(), }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][ - TelemetrySecuityListsTaskConstants.TYPE - ].createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(mockReceiver.fetchTrustedApplications).not.toHaveBeenCalled(); - }); + const mockTelemetryEventsSender = createMockTelemetryEventsSender(); + const mockTelemetryReceiver = createMockTelemetryReceiver(); + const telemetrySecurityListTaskConfig = createTelemetrySecurityListTaskConfig(1); - test('the exception list task should query elastic if telemetry opted in', async () => { - const mockSender = createMockTelemetryEventsSender(true); - const mockTaskManager = taskManagerMock.createSetup(); - const mockReceiver = createMockTelemetryReceiver(); - const telemetryTrustedAppsTask = new MockExceptionListsTask( + await telemetrySecurityListTaskConfig.runTask( + 'test-id', logger, - mockTaskManager, - mockSender, - mockReceiver + mockTelemetryReceiver, + mockTelemetryEventsSender, + testTaskExecutionPeriod ); - const mockTaskInstance = { - id: TelemetrySecuityListsTaskConstants.TYPE, - runAt: new Date(), - attempts: 0, - ownerId: '', - status: TaskStatus.Running, - startedAt: new Date(), - scheduledAt: new Date(), - retryAt: new Date(), - params: {}, - state: {}, - taskType: TelemetrySecuityListsTaskConstants.TYPE, - }; - const createTaskRunner = - mockTaskManager.registerTaskDefinitions.mock.calls[0][0][ - TelemetrySecuityListsTaskConstants.TYPE - ].createTaskRunner; - const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); - await taskRunner.run(); - expect(telemetryTrustedAppsTask.runTask).toHaveBeenCalled(); + expect(mockTelemetryReceiver.fetchTrustedApplications).toHaveBeenCalled(); + expect(mockTelemetryReceiver.fetchEndpointList).toHaveBeenCalledWith(ENDPOINT_LIST_ID); + expect(mockTelemetryReceiver.fetchEndpointList).toHaveBeenCalledWith( + ENDPOINT_EVENT_FILTERS_LIST_ID + ); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts index fe2039419b02d..3fead5ae33be8 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts @@ -5,17 +5,11 @@ * 2.0. */ -import moment from 'moment'; import { Logger } from 'src/core/server'; import { ENDPOINT_LIST_ID, ENDPOINT_EVENT_FILTERS_LIST_ID, } from '@kbn/securitysolution-list-constants'; -import { - ConcreteTaskInstance, - TaskManagerSetupContract, - TaskManagerStartContract, -} from '../../../../../task_manager/server'; import { LIST_ENDPOINT_EXCEPTION, LIST_ENDPOINT_EVENT_FILTER, @@ -25,119 +19,64 @@ import { import { batchTelemetryRecords, templateExceptionList } from '../helpers'; import { TelemetryEventsSender } from '../sender'; import { TelemetryReceiver } from '../receiver'; - -export const TelemetrySecuityListsTaskConstants = { - TIMEOUT: '3m', - TYPE: 'security:telemetry-lists', - INTERVAL: '24h', - VERSION: '1.0.0', -}; - -const MAX_TELEMETRY_BATCH = 1_000; - -export class TelemetryExceptionListsTask { - private readonly logger: Logger; - private readonly sender: TelemetryEventsSender; - private readonly receiver: TelemetryReceiver; - - constructor( - logger: Logger, - taskManager: TaskManagerSetupContract, - sender: TelemetryEventsSender, - receiver: TelemetryReceiver - ) { - this.logger = logger; - this.sender = sender; - this.receiver = receiver; - - taskManager.registerTaskDefinitions({ - [TelemetrySecuityListsTaskConstants.TYPE]: { - title: 'Security Solution Lists Telemetry', - timeout: TelemetrySecuityListsTaskConstants.TIMEOUT, - createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { - const { state } = taskInstance; - - return { - run: async () => { - const taskExecutionTime = moment().utc().toISOString(); - const hits = await this.runTask(taskInstance.id); - - return { - state: { - lastExecutionTimestamp: taskExecutionTime, - runs: (state.runs || 0) + 1, - hits, - }, - }; - }, - cancel: async () => {}, - }; - }, - }, - }); - } - - public start = async (taskManager: TaskManagerStartContract) => { - try { - await taskManager.ensureScheduled({ - id: this.getTaskId(), - taskType: TelemetrySecuityListsTaskConstants.TYPE, - scope: ['securitySolution'], - schedule: { - interval: TelemetrySecuityListsTaskConstants.INTERVAL, - }, - state: { runs: 0 }, - params: { version: TelemetrySecuityListsTaskConstants.VERSION }, - }); - } catch (e) { - this.logger.error(`Error scheduling task, received ${e.message}`); - } - }; - - private getTaskId = (): string => { - return `${TelemetrySecuityListsTaskConstants.TYPE}:${TelemetrySecuityListsTaskConstants.VERSION}`; - }; - - public runTask = async (taskId: string) => { - if (taskId !== this.getTaskId()) { - return 0; - } - - const isOptedIn = await this.sender.isTelemetryOptedIn(); - if (!isOptedIn) { - return 0; - } - - // Lists Telemetry: Trusted Applications - - const trustedApps = await this.receiver.fetchTrustedApplications(); - const trustedAppsJson = templateExceptionList(trustedApps.data, LIST_TRUSTED_APPLICATION); - this.logger.debug(`Trusted Apps: ${trustedAppsJson}`); - - batchTelemetryRecords(trustedAppsJson, MAX_TELEMETRY_BATCH).forEach((batch) => - this.sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch) - ); - - // Lists Telemetry: Endpoint Exceptions - - const epExceptions = await this.receiver.fetchEndpointList(ENDPOINT_LIST_ID); - const epExceptionsJson = templateExceptionList(epExceptions.data, LIST_ENDPOINT_EXCEPTION); - this.logger.debug(`EP Exceptions: ${epExceptionsJson}`); - - batchTelemetryRecords(epExceptionsJson, MAX_TELEMETRY_BATCH).forEach((batch) => - this.sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch) - ); - - // Lists Telemetry: Endpoint Event Filters - - const epFilters = await this.receiver.fetchEndpointList(ENDPOINT_EVENT_FILTERS_LIST_ID); - const epFiltersJson = templateExceptionList(epFilters.data, LIST_ENDPOINT_EVENT_FILTER); - this.logger.debug(`EP Event Filters: ${epFiltersJson}`); - - batchTelemetryRecords(epFiltersJson, MAX_TELEMETRY_BATCH).forEach((batch) => - this.sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch) - ); - - return trustedAppsJson.length + epExceptionsJson.length + epFiltersJson.length; +import { TaskExecutionPeriod } from '../task'; + +export function createTelemetrySecurityListTaskConfig(maxTelemetryBatch: number) { + return { + type: 'security:telemetry-lists', + title: 'Security Solution Lists Telemetry', + interval: '24h', + timeout: '3m', + version: '1.0.0', + runTask: async ( + taskId: string, + logger: Logger, + receiver: TelemetryReceiver, + sender: TelemetryEventsSender, + taskExecutionPeriod: TaskExecutionPeriod + ) => { + let count = 0; + + // Lists Telemetry: Trusted Applications + + const trustedApps = await receiver.fetchTrustedApplications(); + if (trustedApps?.data) { + const trustedAppsJson = templateExceptionList(trustedApps.data, LIST_TRUSTED_APPLICATION); + logger.debug(`Trusted Apps: ${trustedAppsJson}`); + count += trustedAppsJson.length; + + batchTelemetryRecords(trustedAppsJson, maxTelemetryBatch).forEach((batch) => + sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch) + ); + } + + // Lists Telemetry: Endpoint Exceptions + + const epExceptions = await receiver.fetchEndpointList(ENDPOINT_LIST_ID); + if (epExceptions?.data) { + const epExceptionsJson = templateExceptionList(epExceptions.data, LIST_ENDPOINT_EXCEPTION); + logger.debug(`EP Exceptions: ${epExceptionsJson}`); + count += epExceptionsJson.length; + + batchTelemetryRecords(epExceptionsJson, maxTelemetryBatch).forEach((batch) => + sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch) + ); + } + + // Lists Telemetry: Endpoint Event Filters + + const epFilters = await receiver.fetchEndpointList(ENDPOINT_EVENT_FILTERS_LIST_ID); + if (epFilters?.data) { + const epFiltersJson = templateExceptionList(epFilters.data, LIST_ENDPOINT_EVENT_FILTER); + logger.debug(`EP Event Filters: ${epFiltersJson}`); + count += epFiltersJson.length; + + batchTelemetryRecords(epFiltersJson, maxTelemetryBatch).forEach((batch) => + sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch) + ); + } + + return count; + }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/helpers.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/helpers.ts index a33b8be0c2f31..c857e7fa38a27 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/helpers.ts @@ -6,6 +6,7 @@ */ import { omit } from 'lodash/fp'; +import { transformDataToNdjson } from '@kbn/securitysolution-utils'; import { ExportedTimelines, @@ -15,8 +16,6 @@ import { import { NoteSavedObject } from '../../../../../../common/types/timeline/note'; import { PinnedEventSavedObject } from '../../../../../../common/types/timeline/pinned_event'; -import { transformDataToNdjson } from '../../../../../utils/read_stream/create_stream_from_ndjson'; - import { FrameworkRequest } from '../../../../framework'; import * as noteLib from '../../../saved_object/notes'; import * as pinnedEventLib from '../../../saved_object/pinned_events'; diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index f0a91f8b06c00..d54ed18af01e3 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -109,6 +109,7 @@ import { ctiFieldMap } from './lib/detection_engine/rule_types/field_maps/cti'; import { legacyRulesNotificationAlertType } from './lib/detection_engine/notifications/legacy_rules_notification_alert_type'; // eslint-disable-next-line no-restricted-imports import { legacyIsNotificationAlertExecutor } from './lib/detection_engine/notifications/legacy_types'; +import { createSecurityRuleTypeWrapper } from './lib/detection_engine/rule_types/create_security_rule_type_wrapper'; import { IEventLogClientService, IEventLogService } from '../../event_log/server'; import { registerEventLogProvider } from './lib/detection_engine/rule_execution_log/event_log_adapter/register_event_log_provider'; @@ -268,20 +269,34 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S // Register rule types via rule-registry const createRuleOptions: CreateRuleOptions = { experimentalFeatures, + logger: this.logger, + ml: plugins.ml, + version: this.context.env.packageInfo.version, + }; + + const securityRuleTypeWrapper = createSecurityRuleTypeWrapper({ lists: plugins.lists, logger: this.logger, config: this.config, - ml: plugins.ml, ruleDataClient, eventLogService, - version: this.context.env.packageInfo.version, - }; + }); - this.setupPlugins.alerting.registerType(createEqlAlertType(createRuleOptions)); - this.setupPlugins.alerting.registerType(createIndicatorMatchAlertType(createRuleOptions)); - this.setupPlugins.alerting.registerType(createMlAlertType(createRuleOptions)); - this.setupPlugins.alerting.registerType(createQueryAlertType(createRuleOptions)); - this.setupPlugins.alerting.registerType(createThresholdAlertType(createRuleOptions)); + this.setupPlugins.alerting.registerType( + securityRuleTypeWrapper(createEqlAlertType(createRuleOptions)) + ); + this.setupPlugins.alerting.registerType( + securityRuleTypeWrapper(createIndicatorMatchAlertType(createRuleOptions)) + ); + this.setupPlugins.alerting.registerType( + securityRuleTypeWrapper(createMlAlertType(createRuleOptions)) + ); + this.setupPlugins.alerting.registerType( + securityRuleTypeWrapper(createQueryAlertType(createRuleOptions)) + ); + this.setupPlugins.alerting.registerType( + securityRuleTypeWrapper(createThresholdAlertType(createRuleOptions)) + ); } // TODO We need to get the endpoint routes inside of initRoutes diff --git a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.test.ts b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.test.ts deleted file mode 100644 index c3163da6ac949..0000000000000 --- a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.test.ts +++ /dev/null @@ -1,71 +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 { transformDataToNdjson } from './create_stream_from_ndjson'; -import { ImportRulesSchemaDecoded } from '../../../common/detection_engine/schemas/request/import_rules_schema'; -import { getRulesSchemaMock } from '../../../common/detection_engine/schemas/response/rules_schema.mocks'; - -export const getOutputSample = (): Partial<ImportRulesSchemaDecoded> => ({ - rule_id: 'rule-1', - output_index: '.siem-signals', - risk_score: 50, - description: 'some description', - from: 'now-5m', - to: 'now', - index: ['index-1'], - name: 'some-name', - severity: 'low', - interval: '5m', - type: 'query', -}); - -export const getSampleAsNdjson = (sample: Partial<ImportRulesSchemaDecoded>): string => { - return `${JSON.stringify(sample)}\n`; -}; - -describe('create_rules_stream_from_ndjson', () => { - describe('transformDataToNdjson', () => { - test('if rules are empty it returns an empty string', () => { - const ruleNdjson = transformDataToNdjson([]); - expect(ruleNdjson).toEqual(''); - }); - - test('single rule will transform with new line ending character for ndjson', () => { - const rule = getRulesSchemaMock(); - const ruleNdjson = transformDataToNdjson([rule]); - expect(ruleNdjson.endsWith('\n')).toBe(true); - }); - - test('multiple rules will transform with two new line ending characters for ndjson', () => { - const result1 = getRulesSchemaMock(); - const result2 = getRulesSchemaMock(); - result2.id = 'some other id'; - result2.rule_id = 'some other id'; - result2.name = 'Some other rule'; - - const ruleNdjson = transformDataToNdjson([result1, result2]); - // this is how we count characters in JavaScript :-) - const count = ruleNdjson.split('\n').length - 1; - expect(count).toBe(2); - }); - - test('you can parse two rules back out without errors', () => { - const result1 = getRulesSchemaMock(); - const result2 = getRulesSchemaMock(); - result2.id = 'some other id'; - result2.rule_id = 'some other id'; - result2.name = 'Some other rule'; - - const ruleNdjson = transformDataToNdjson([result1, result2]); - const ruleStrings = ruleNdjson.split('\n'); - const reParsed1 = JSON.parse(ruleStrings[0]); - const reParsed2 = JSON.parse(ruleStrings[1]); - expect(reParsed1).toEqual(result1); - expect(reParsed2).toEqual(result2); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts index 42f1b467ed4c2..eb5abaee8cd3b 100644 --- a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts +++ b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts @@ -48,12 +48,3 @@ export const createLimitStream = (limit: number): Transform => { }, }); }; - -export const transformDataToNdjson = (data: unknown[]): string => { - if (data.length !== 0) { - const dataString = data.map((rule) => JSON.stringify(rule)).join('\n'); - return `${dataString}\n`; - } else { - return ''; - } -}; diff --git a/x-pack/plugins/timelines/common/types/timeline/cells/index.ts b/x-pack/plugins/timelines/common/types/timeline/cells/index.ts index 354a8b45e914d..ce22d87c0a59a 100644 --- a/x-pack/plugins/timelines/common/types/timeline/cells/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/cells/index.ts @@ -7,21 +7,26 @@ import { EuiDataGridCellValueElementProps } from '@elastic/eui'; import { RowRenderer } from '../../..'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { Filter } from '../../../../../../../src/plugins/data/public'; import { Ecs } from '../../../ecs'; import { BrowserFields, TimelineNonEcsData } from '../../../search_strategy'; import { ColumnHeaderOptions } from '../columns'; /** The following props are provided to the function called by `renderCellValue` */ export type CellValueElementProps = EuiDataGridCellValueElementProps & { + asPlainText?: boolean; + browserFields?: BrowserFields; data: TimelineNonEcsData[]; + ecsData?: Ecs; eventId: string; // _id + globalFilters?: Filter[]; header: ColumnHeaderOptions; isDraggable: boolean; linkValues: string[] | undefined; - timelineId: string; + rowRenderers?: RowRenderer[]; // eslint-disable-next-line @typescript-eslint/no-explicit-any setFlyoutAlert?: (data: any) => void; - ecsData?: Ecs; - rowRenderers?: RowRenderer[]; - browserFields?: BrowserFields; + timelineId: string; + truncate?: boolean; }; diff --git a/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx b/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx index 644b38d551337..bd4cd2d7192df 100644 --- a/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx +++ b/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx @@ -8,9 +8,10 @@ import { ReactNode } from 'react'; import { EuiDataGridColumn, EuiDataGridColumnCellActionProps } from '@elastic/eui'; -import { Filter, IFieldSubType } from '../../../../../../../src/plugins/data/common'; +import { IFieldSubType } from '../../../../../../../src/plugins/data/common'; import { BrowserFields } from '../../../search_strategy/index_fields'; import { TimelineNonEcsData } from '../../../search_strategy/timeline'; +import { Ecs } from '../../../ecs'; export type ColumnHeaderType = 'not-filtered' | 'text-filter'; @@ -45,14 +46,16 @@ export type ColumnId = string; export type TGridCellAction = ({ browserFields, data, - globalFilters, + ecsData, + header, pageSize, timelineId, }: { browserFields: BrowserFields; /** each row of data is represented as one TimelineNonEcsData[] */ data: TimelineNonEcsData[][]; - globalFilters?: Filter[]; + ecsData: Ecs[]; + header?: ColumnHeaderOptions; pageSize: number; timelineId: string; }) => (props: EuiDataGridColumnCellActionProps) => ReactNode; diff --git a/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_for_value.tsx b/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_for_value.tsx index 549c2da0d7672..7b8ecdb0f582f 100644 --- a/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_for_value.tsx +++ b/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_for_value.tsx @@ -14,8 +14,8 @@ import { TooltipWithKeyboardShortcut } from '../../tooltip_with_keyboard_shortcu import { createFilter, getAdditionalScreenReaderOnlyContext } from '../utils'; import { HoverActionComponentProps, FilterValueFnArgs } from './types'; -export const FILTER_FOR_VALUE = i18n.translate('xpack.timelines.hoverActions.filterForValue', { - defaultMessage: 'Filter for value', +export const FILTER_FOR_VALUE = i18n.translate('xpack.timelines.hoverActions.filterIn', { + defaultMessage: 'Filter In', }); export const FILTER_FOR_VALUE_KEYBOARD_SHORTCUT = 'f'; @@ -31,6 +31,7 @@ const FilterForValueButton: React.FC<FilterForValueProps> = React.memo( onFilterAdded, ownFocus, onClick, + size, showTooltip = false, value, }) => { @@ -74,6 +75,7 @@ const FilterForValueButton: React.FC<FilterForValueProps> = React.memo( data-test-subj="filter-for-value" iconType="plusInCircle" onClick={filterForValueFn} + size={size} title={FILTER_FOR_VALUE} > {FILTER_FOR_VALUE} @@ -87,9 +89,10 @@ const FilterForValueButton: React.FC<FilterForValueProps> = React.memo( iconSize="s" iconType="plusInCircle" onClick={filterForValueFn} + size={size} /> ), - [Component, defaultFocusedButtonRef, filterForValueFn] + [Component, defaultFocusedButtonRef, filterForValueFn, size] ); return showTooltip ? ( diff --git a/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_out_value.tsx b/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_out_value.tsx index 51f2943ff051e..04fbbab76d850 100644 --- a/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_out_value.tsx +++ b/x-pack/plugins/timelines/public/components/hover_actions/actions/filter_out_value.tsx @@ -14,8 +14,8 @@ import { TooltipWithKeyboardShortcut } from '../../tooltip_with_keyboard_shortcu import { createFilter, getAdditionalScreenReaderOnlyContext } from '../utils'; import { HoverActionComponentProps, FilterValueFnArgs } from './types'; -export const FILTER_OUT_VALUE = i18n.translate('xpack.timelines.hoverActions.filterOutValue', { - defaultMessage: 'Filter out value', +export const FILTER_OUT_VALUE = i18n.translate('xpack.timelines.hoverActions.filterOut', { + defaultMessage: 'Filter Out', }); export const FILTER_OUT_VALUE_KEYBOARD_SHORTCUT = 'o'; @@ -30,6 +30,7 @@ const FilterOutValueButton: React.FC<HoverActionComponentProps & FilterValueFnAr onFilterAdded, ownFocus, onClick, + size, showTooltip = false, value, }) => { @@ -74,6 +75,7 @@ const FilterOutValueButton: React.FC<HoverActionComponentProps & FilterValueFnAr data-test-subj="filter-out-value" iconType="minusInCircle" onClick={filterOutValueFn} + size={size} title={FILTER_OUT_VALUE} > {FILTER_OUT_VALUE} @@ -87,9 +89,10 @@ const FilterOutValueButton: React.FC<HoverActionComponentProps & FilterValueFnAr iconSize="s" iconType="minusInCircle" onClick={filterOutValueFn} + size={size} /> ), - [Component, defaultFocusedButtonRef, filterOutValueFn] + [Component, defaultFocusedButtonRef, filterOutValueFn, size] ); return showTooltip ? ( diff --git a/x-pack/plugins/timelines/public/components/hover_actions/actions/types.ts b/x-pack/plugins/timelines/public/components/hover_actions/actions/types.ts index 5be8fd8904f1a..b6c9e794625e4 100644 --- a/x-pack/plugins/timelines/public/components/hover_actions/actions/types.ts +++ b/x-pack/plugins/timelines/public/components/hover_actions/actions/types.ts @@ -18,11 +18,13 @@ export interface FilterValueFnArgs { } export interface HoverActionComponentProps { + className?: string; defaultFocusedButtonRef?: EuiButtonIconPropsForButton['buttonRef']; field: string; keyboardEvent?: React.KeyboardEvent; ownFocus: boolean; onClick?: () => void; + size?: 'xs' | 's' | 'm'; showTooltip?: boolean; value?: string[] | string | null; } diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/index.test.tsx index 8fbb7f0e62b9c..50764af3c7f2f 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/index.test.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/index.test.tsx @@ -15,6 +15,8 @@ import { defaultHeaders, mockBrowserFields, mockTimelineData, TestProviders } fr import { TimelineTabs } from '../../../../common/types/timeline'; import { TestCellRenderer } from '../../../mock/cell_renderer'; import { mockGlobalState } from '../../../mock/global_state'; +import { EuiDataGridColumn } from '@elastic/eui'; +import { defaultColumnHeaderType } from '../../../store/t_grid/defaults'; const mockSort: Sort[] = [ { @@ -151,5 +153,124 @@ describe('Body', () => { .text() ).toEqual(mockTimelineData[0].ecs.timestamp); }); + + test("timestamp column doesn't render cell actions", () => { + const headersJustTimestamp = defaultHeaders.filter((h) => h.id === '@timestamp'); + const testProps = { + ...props, + columnHeaders: headersJustTimestamp, + data: mockTimelineData.slice(0, 1), + }; + const wrapper = mount( + <TestProviders> + <BodyComponent {...testProps} /> + </TestProviders> + ); + wrapper.update(); + + expect( + wrapper + .find('[data-test-subj="body-data-grid"]') + .first() + .prop<EuiDataGridColumn[]>('columns') + .find((c) => c.id === '@timestamp')?.cellActions + ).toBeUndefined(); + }); + + test("signal.rule.risk_score column doesn't render cell actions", () => { + const columnHeaders = [ + { + category: 'signal', + columnHeaderType: defaultColumnHeaderType, + id: 'signal.rule.risk_score', + type: 'number', + aggregatable: true, + initialWidth: 105, + }, + ]; + const testProps = { + ...props, + columnHeaders, + data: mockTimelineData.slice(0, 1), + }; + const wrapper = mount( + <TestProviders> + <BodyComponent {...testProps} /> + </TestProviders> + ); + wrapper.update(); + + expect( + wrapper + .find('[data-test-subj="body-data-grid"]') + .first() + .prop<EuiDataGridColumn[]>('columns') + .find((c) => c.id === 'signal.rule.risk_score')?.cellActions + ).toBeUndefined(); + }); + + test("signal.reason column doesn't render cell actions", () => { + const columnHeaders = [ + { + category: 'signal', + columnHeaderType: defaultColumnHeaderType, + id: 'signal.reason', + type: 'string', + aggregatable: true, + initialWidth: 450, + }, + ]; + const testProps = { + ...props, + columnHeaders, + data: mockTimelineData.slice(0, 1), + }; + const wrapper = mount( + <TestProviders> + <BodyComponent {...testProps} /> + </TestProviders> + ); + wrapper.update(); + + expect( + wrapper + .find('[data-test-subj="body-data-grid"]') + .first() + .prop<EuiDataGridColumn[]>('columns') + .find((c) => c.id === 'signal.reason')?.cellActions + ).toBeUndefined(); + }); + }); + + test("signal.rule.risk_score column doesn't render cell actions", () => { + const columnHeaders = [ + { + category: 'signal', + columnHeaderType: defaultColumnHeaderType, + id: 'signal.rule.risk_score', + type: 'number', + aggregatable: true, + initialWidth: 105, + }, + ]; + const testProps = { + ...props, + columnHeaders, + data: mockTimelineData.slice(0, 1), + }; + const wrapper = mount( + <TestProviders> + <BodyComponent {...testProps} /> + </TestProviders> + ); + wrapper.update(); + + expect( + wrapper + .find('[data-test-subj="body-data-grid"]') + .first() + .prop<EuiDataGridColumn[]>('columns') + .find((c) => c.id === 'signal.rule.risk_score')?.cellActions + ).toBeUndefined(); }); }); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx index 83079e0cdc2fe..619571a0c8e81 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx @@ -145,6 +145,9 @@ const EuiDataGridContainer = styled.div<{ hideLastPage: boolean }>` } `; +const FIELDS_WITHOUT_CELL_ACTIONS = ['@timestamp', 'signal.rule.risk_score', 'signal.reason']; +const hasCellActions = (columnId?: string) => + columnId && FIELDS_WITHOUT_CELL_ACTIONS.indexOf(columnId) < 0; const transformControlColumns = ({ actionColumnsWidth, columnHeaders, @@ -636,7 +639,6 @@ export const BodyComponent = React.memo<StatefulBodyProps>( setEventsDeleted, hasAlertsCrudPermissions, ]); - const columnsWithCellActions: EuiDataGridColumn[] = useMemo( () => columnHeaders.map((header) => { @@ -644,18 +646,24 @@ export const BodyComponent = React.memo<StatefulBodyProps>( tGridCellAction({ browserFields, data: data.map((row) => row.data), - globalFilters: filters, + ecsData: data.map((row) => row.ecs), + header: columnHeaders.find((h) => h.id === header.id), pageSize, timelineId: id, }); return { ...header, - cellActions: - header.tGridCellActions?.map(buildAction) ?? defaultCellActions?.map(buildAction), + ...(hasCellActions(header.id) + ? { + cellActions: + header.tGridCellActions?.map(buildAction) ?? + defaultCellActions?.map(buildAction), + } + : {}), }; }), - [browserFields, columnHeaders, data, defaultCellActions, id, pageSize, filters] + [columnHeaders, defaultCellActions, browserFields, data, pageSize, id] ); const renderTGridCellValue = useMemo(() => { @@ -663,9 +671,9 @@ export const BodyComponent = React.memo<StatefulBodyProps>( columnId, rowIndex, setCellProps, + isDetails, }): React.ReactElement | null => { const pageRowIndex = getPageRowIndex(rowIndex, pageSize); - const rowData = pageRowIndex < data.length ? data[pageRowIndex].data : null; const header = columnHeaders.find((h) => h.id === columnId); const eventId = pageRowIndex < data.length ? data[pageRowIndex]._id : null; @@ -687,34 +695,36 @@ export const BodyComponent = React.memo<StatefulBodyProps>( } return renderCellValue({ + browserFields, columnId: header.id, - eventId, data: rowData, + ecsData: ecs, + eventId, + globalFilters: filters, header, + isDetails, isDraggable: false, isExpandable: true, isExpanded: false, - isDetails: false, linkValues: getOr([], header.linkField ?? '', ecs), rowIndex, - setCellProps, - timelineId: tabType != null ? `${id}-${tabType}` : id, - ecsData: ecs, - browserFields, rowRenderers, + setCellProps, + timelineId: id, + truncate: isDetails ? false : true, }) as React.ReactElement; }; return Cell; }, [ + browserFields, columnHeaders, data, + filters, id, + pageSize, renderCellValue, - tabType, - theme, - browserFields, rowRenderers, - pageSize, + theme, ]); const onChangeItemsPerPage = useCallback( diff --git a/x-pack/plugins/timelines/public/components/t_grid/event_rendered_view/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/event_rendered_view/index.tsx index 6f69c54233858..91bb6ad1dac0b 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/event_rendered_view/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/event_rendered_view/index.tsx @@ -180,19 +180,21 @@ const EventRenderedViewComponent = ({ rowRenderer.isInstance(ecsData) ); return ( - <EuiFlexGroup gutterSize="none" direction="column"> + <EuiFlexGroup gutterSize="none" direction="column" className="eui-fullWidth"> {reason && <EuiFlexItem>{reason}</EuiFlexItem>} {rowRenderersValid.length > 0 && rowRenderersValid.map((rowRenderer) => ( <> <EuiHorizontalRule size="half" margin="xs" /> - <EventRenderedFlexItem> - {rowRenderer.renderRow({ - browserFields, - data: ecsData, - isDraggable: false, - timelineId: 'NONE', - })} + <EventRenderedFlexItem className="eui-xScroll"> + <div className="eui-displayInlineBlock"> + {rowRenderer.renderRow({ + browserFields, + data: ecsData, + isDraggable: false, + timelineId: 'NONE', + })} + </div> </EventRenderedFlexItem> </> ))} diff --git a/x-pack/plugins/transform/kibana.json b/x-pack/plugins/transform/kibana.json index 5e1c1fb938a86..f47b018dd1d26 100644 --- a/x-pack/plugins/transform/kibana.json +++ b/x-pack/plugins/transform/kibana.json @@ -17,6 +17,7 @@ "optionalPlugins": [ "security", "usageCollection", + "spaces", "alerting" ], "configPath": ["xpack", "transform"], diff --git a/x-pack/plugins/transform/public/__mocks__/shared_imports.ts b/x-pack/plugins/transform/public/__mocks__/shared_imports.ts index ae072e6666e4a..e0788d7747e65 100644 --- a/x-pack/plugins/transform/public/__mocks__/shared_imports.ts +++ b/x-pack/plugins/transform/public/__mocks__/shared_imports.ts @@ -13,7 +13,7 @@ export const useRequest = jest.fn(() => ({ error: null, data: undefined, })); -export const createSavedSearchesLoader = jest.fn(); +export const getSavedSearch = jest.fn(); // just passing through the reimports export { getMlSharedImports, ES_CLIENT_TOTAL_HITS_RELATION } from '../../../ml/public'; diff --git a/x-pack/plugins/transform/public/app/app_dependencies.tsx b/x-pack/plugins/transform/public/app/app_dependencies.tsx index c39aa5a49e5e9..d3f356f3e83b3 100644 --- a/x-pack/plugins/transform/public/app/app_dependencies.tsx +++ b/x-pack/plugins/transform/public/app/app_dependencies.tsx @@ -10,6 +10,7 @@ import type { DataPublicPluginStart } from 'src/plugins/data/public'; import type { SavedObjectsStart } from 'src/plugins/saved_objects/public'; import type { ScopedHistory } from 'kibana/public'; import type { SharePluginStart } from 'src/plugins/share/public'; +import type { SpacesPluginStart } from '../../../spaces/public'; import { useKibana } from '../../../../../src/plugins/kibana_react/public'; import type { Storage } from '../../../../../src/plugins/kibana_utils/public'; @@ -32,6 +33,7 @@ export interface AppDependencies { savedObjectsPlugin: SavedObjectsStart; share: SharePluginStart; ml: GetMlSharedImportsReturnType; + spaces?: SpacesPluginStart; } export const useAppDependencies = () => { diff --git a/x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts b/x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts index 3e85f5d4d49a4..db5fd82808a91 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_search_items/common.ts @@ -20,12 +20,10 @@ import { isIndexPattern } from '../../../../common/types/index_pattern'; export type SavedSearchQuery = object; type IndexPatternId = string; -type SavedSearchId = string; let indexPatternCache: Array<SimpleSavedObject<Record<string, any>>> = []; let fullIndexPatterns; let currentIndexPattern = null; -let currentSavedSearch = null; export let refreshIndexPatterns: () => Promise<unknown>; @@ -76,11 +74,6 @@ export function loadCurrentIndexPattern( return currentIndexPattern; } -export function loadCurrentSavedSearch(savedSearches: any, savedSearchId: SavedSearchId) { - currentSavedSearch = savedSearches.get(savedSearchId); - return currentSavedSearch; -} - export interface SearchItems { indexPattern: IndexPattern; savedSearch: any; diff --git a/x-pack/plugins/transform/public/app/hooks/use_search_items/use_search_items.ts b/x-pack/plugins/transform/public/app/hooks/use_search_items/use_search_items.ts index 44e3cc347824d..bd225ae9d0a32 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_search_items/use_search_items.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_search_items/use_search_items.ts @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { isIndexPattern } from '../../../../common/types/index_pattern'; -import { createSavedSearchesLoader } from '../../../shared_imports'; +import { getSavedSearch, getSavedSearchUrlConflictMessage } from '../../../shared_imports'; import { useAppDependencies } from '../../app_dependencies'; @@ -20,7 +20,6 @@ import { getIndexPatternIdByTitle, loadCurrentIndexPattern, loadIndexPatterns, - loadCurrentSavedSearch, SearchItems, } from './common'; @@ -32,10 +31,6 @@ export const useSearchItems = (defaultSavedObjectId: string | undefined) => { const indexPatterns = appDeps.data.indexPatterns; const uiSettings = appDeps.uiSettings; const savedObjectsClient = appDeps.savedObjects.client; - const savedSearches = createSavedSearchesLoader({ - savedObjectsClient, - savedObjects: appDeps.savedObjectsPlugin, - }); const [searchItems, setSearchItems] = useState<SearchItems | undefined>(undefined); @@ -52,7 +47,16 @@ export const useSearchItems = (defaultSavedObjectId: string | undefined) => { } try { - fetchedSavedSearch = await loadCurrentSavedSearch(savedSearches, id); + fetchedSavedSearch = await getSavedSearch(id, { + search: appDeps.data.search, + savedObjectsClient: appDeps.savedObjects.client, + spaces: appDeps.spaces, + }); + + if (fetchedSavedSearch?.sharingSavedObjectProps?.errorJSON) { + setError(await getSavedSearchUrlConflictMessage(fetchedSavedSearch)); + return; + } } catch (e) { // Just let fetchedSavedSearch stay undefined in case it doesn't exist. } diff --git a/x-pack/plugins/transform/public/app/mount_management_section.ts b/x-pack/plugins/transform/public/app/mount_management_section.ts index 1d39d233f8284..1747330818547 100644 --- a/x-pack/plugins/transform/public/app/mount_management_section.ts +++ b/x-pack/plugins/transform/public/app/mount_management_section.ts @@ -29,7 +29,7 @@ export async function mountManagementSection( const startServices = await getStartServices(); const [core, plugins] = startServices; const { application, chrome, docLinks, i18n, overlays, savedObjects, uiSettings } = core; - const { data, share } = plugins; + const { data, share, spaces } = plugins; const { docTitle } = chrome; // Initialize services @@ -53,6 +53,7 @@ export async function mountManagementSection( history, savedObjectsPlugin: plugins.savedObjects, share, + spaces, ml: await getMlSharedImports(), }; diff --git a/x-pack/plugins/transform/public/plugin.ts b/x-pack/plugins/transform/public/plugin.ts index 4ed4e64070344..da280452c1f0f 100644 --- a/x-pack/plugins/transform/public/plugin.ts +++ b/x-pack/plugins/transform/public/plugin.ts @@ -13,6 +13,7 @@ import type { HomePublicPluginSetup } from 'src/plugins/home/public'; import type { SavedObjectsStart } from 'src/plugins/saved_objects/public'; import type { ManagementSetup } from 'src/plugins/management/public'; import type { SharePluginStart } from 'src/plugins/share/public'; +import type { SpacesApi } from '../../spaces/public'; import { registerFeature } from './register_feature'; import type { PluginSetupContract as AlertingSetup } from '../../alerting/public'; import type { TriggersAndActionsUIPublicPluginSetup } from '../../triggers_actions_ui/public'; @@ -24,6 +25,7 @@ export interface PluginsDependencies { home: HomePublicPluginSetup; savedObjects: SavedObjectsStart; share: SharePluginStart; + spaces?: SpacesApi; alerting?: AlertingSetup; triggersActionsUi?: TriggersAndActionsUIPublicPluginSetup; } diff --git a/x-pack/plugins/transform/public/shared_imports.ts b/x-pack/plugins/transform/public/shared_imports.ts index edd27fd43c2af..b8f5d88205858 100644 --- a/x-pack/plugins/transform/public/shared_imports.ts +++ b/x-pack/plugins/transform/public/shared_imports.ts @@ -5,9 +5,12 @@ * 2.0. */ -export { createSavedSearchesLoader } from '../../../../src/plugins/discover/public'; export { XJsonMode } from '@kbn/ace'; export { UseRequestConfig, useRequest } from '../../../../src/plugins/es_ui_shared/public'; +export { + getSavedSearch, + getSavedSearchUrlConflictMessage, +} from '../../../../src/plugins/discover/public'; export { getMlSharedImports, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 642668bcecf34..ab62d33fce5f5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1162,8 +1162,6 @@ "core.euiLink.external.ariaLabel": "外部リンク", "core.euiLink.newTarget.screenReaderOnlyText": "(新しいタブまたはウィンドウで開く)", "core.euiMarkdownEditorFooter.closeButton": "閉じる", - "core.euiMarkdownEditorFooter.descriptionPrefix": "このエディターは使用します", - "core.euiMarkdownEditorFooter.descriptionSuffix": "これらの追加の構文プラグインを利用して、リッチコンテンツをテキストに追加することもできます。", "core.euiMarkdownEditorFooter.errorsTitle": "エラー", "core.euiMarkdownEditorFooter.openUploadModal": "ファイルのアップロードモーダルを開く", "core.euiMarkdownEditorFooter.showMarkdownHelp": "マークダウンヘルプを表示", @@ -2992,13 +2990,11 @@ "home.tutorial.card.sampleDataDescription": "これらの「ワンクリック」データセットで Kibana の探索を始めましょう。", "home.tutorial.card.sampleDataTitle": "サンプルデータ", "home.tutorial.elasticCloudButtonLabel": "Elastic Cloud", - "home.tutorial.instruction.copyButtonLabel": "スニペットをコピー", "home.tutorial.instructionSet.checkStatusButtonLabel": "ステータスを確認", "home.tutorial.instructionSet.customizeLabel": "コードスニペットのカスタマイズ", "home.tutorial.instructionSet.noDataLabel": "データが見つかりません", "home.tutorial.instructionSet.statusCheckTitle": "ステータス確認", "home.tutorial.instructionSet.successLabel": "成功", - "home.tutorial.instructionSet.toggleAriaLabel": "コマンドパラメーターの可視性を調整します", "home.tutorial.introduction.betaLabel": "ベータ", "home.tutorial.introduction.imageAltDescription": "プライマリダッシュボードのスクリーンショット。", "home.tutorial.introduction.viewButtonLabel": "エクスポートされたフィールドを表示", @@ -4912,6 +4908,16 @@ "visTypeMetric.colorModes.backgroundOptionLabel": "背景", "visTypeMetric.colorModes.labelsOptionLabel": "ラベル", "visTypeMetric.colorModes.noneOptionLabel": "なし", + "visTypeMetric.metricDescription": "計算結果を単独の数字として表示します。", + "visTypeMetric.metricTitle": "メトリック", + "visTypeMetric.params.color.useForLabel": "使用する色", + "visTypeMetric.params.rangesTitle": "範囲", + "visTypeMetric.params.settingsTitle": "設定", + "visTypeMetric.params.showTitleLabel": "タイトルを表示", + "visTypeMetric.params.style.fontSizeLabel": "ポイント単位のメトリックフォントサイズ", + "visTypeMetric.params.style.styleTitle": "スタイル", + "visTypeMetric.schemas.metricTitle": "メトリック", + "visTypeMetric.schemas.splitGroupTitle": "グループを分割", "expressionMetricVis.function.dimension.splitGroup": "グループを分割", "expressionMetricVis.function.bgFill.help": "html 16 進数コード(#123456)、html 色(red、blue)、または rgba 値(rgba(255,255,255,1))。", "expressionMetricVis.function.bucket.help": "バケットディメンションの構成です。", @@ -4927,16 +4933,6 @@ "expressionMetricVis.function.showLabels.help": "メトリック値の下にラベルを表示します。", "expressionMetricVis.function.subText.help": "メトリックの下に表示するカスタムテキスト", "expressionMetricVis.function.useRanges.help": "有効な色範囲です。", - "visTypeMetric.metricDescription": "計算結果を単独の数字として表示します。", - "visTypeMetric.metricTitle": "メトリック", - "visTypeMetric.params.color.useForLabel": "使用する色", - "visTypeMetric.params.rangesTitle": "範囲", - "visTypeMetric.params.settingsTitle": "設定", - "visTypeMetric.params.showTitleLabel": "タイトルを表示", - "visTypeMetric.params.style.fontSizeLabel": "ポイント単位のメトリックフォントサイズ", - "visTypeMetric.params.style.styleTitle": "スタイル", - "visTypeMetric.schemas.metricTitle": "メトリック", - "visTypeMetric.schemas.splitGroupTitle": "グループを分割", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.deprecation": "Visualizeの円グラフのレガシーグラフライブラリは廃止予定であり、8.0以降ではサポートされません。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.description": "Visualizeで円グラフのレガシーグラフライブラリを有効にします。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.name": "円グラフのレガシーグラフライブラリ", @@ -6905,7 +6901,6 @@ "xpack.apm.tutorial.apmServer.statusCheck.text": "APM エージェントの導入を開始する前に、APM Server が動作していることを確認してください。", "xpack.apm.tutorial.apmServer.statusCheck.title": "APM Server ステータス", "xpack.apm.tutorial.apmServer.title": "APM Server", - "xpack.apm.tutorial.copySnippet": "スニペットをコピー", "xpack.apm.tutorial.djangoClient.configure.commands.addAgentComment": "インストールされたアプリにエージェントを追加します", "xpack.apm.tutorial.djangoClient.configure.commands.addTracingMiddlewareComment": "パフォーマンスメトリックを送信するには、追跡ミドルウェアを追加します。", "xpack.apm.tutorial.djangoClient.configure.commands.allowedCharactersComment": "a-z、A-Z、0-9、-、_、スペース", @@ -10725,7 +10720,6 @@ "xpack.fleet.epm.detailsTitle": "詳細", "xpack.fleet.epm.errorLoadingNotice": "NOTICE.txtの読み込みエラー", "xpack.fleet.epm.featuresLabel": "機能", - "xpack.fleet.epm.illustrationAltText": "統合の例", "xpack.fleet.epm.install.packageInstallError": "{pkgName} {pkgVersion}のインストールエラー", "xpack.fleet.epm.install.packageUpdateError": "{pkgName} {pkgVersion}の更新エラー", "xpack.fleet.epm.licenseLabel": "ライセンス", @@ -10748,7 +10742,6 @@ "xpack.fleet.epm.packageDetailsNav.packageCustomLinkText": "高度な設定", "xpack.fleet.epm.packageDetailsNav.packagePoliciesLinkText": "ポリシー", "xpack.fleet.epm.packageDetailsNav.settingsLinkText": "設定", - "xpack.fleet.epm.pageSubtitle": "Elasticエージェントを使用して一般的なアプリやサービスからデータを収集します", "xpack.fleet.epm.releaseBadge.betaDescription": "この統合は本番環境用ではありません。", "xpack.fleet.epm.releaseBadge.betaLabel": "ベータ", "xpack.fleet.epm.releaseBadge.experimentalDescription": "この統合は、急に変更されたり、将来のリリースで削除されたりする可能性があります。", @@ -10761,7 +10754,6 @@ "xpack.fleet.epm.usedByLabel": "エージェントポリシー", "xpack.fleet.epm.versionLabel": "バージョン", "xpack.fleet.epmList.allPackagesFilterLinkText": "すべて", - "xpack.fleet.epmList.allTitle": "カテゴリで参照", "xpack.fleet.epmList.installedTitle": "インストールされている統合", "xpack.fleet.epmList.missingIntegrationPlaceholder": "検索用語と一致する統合が見つかりませんでした。別のキーワードを試すか、左側のカテゴリを使用して参照してください。", "xpack.fleet.epmList.noPackagesFoundPlaceholder": "パッケージが見つかりません", @@ -10835,12 +10827,10 @@ "xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注:", "xpack.fleet.hostsInput.addRow": "行の追加", "xpack.fleet.initializationErrorMessageTitle": "Fleet を初期化できません", - "xpack.fleet.integrations.beatsModulesLink": "Beatsモジュール", "xpack.fleet.integrations.customInputsLink": "カスタム入力", "xpack.fleet.integrations.discussForumLink": "ディスカッションフォーラム", "xpack.fleet.integrations.installPackage.installingPackageButtonLabel": "{title} アセットをインストールしています", "xpack.fleet.integrations.installPackage.installPackageButtonLabel": "{title}アセットをインストール", - "xpack.fleet.integrations.missing": "統合が表示されない場合{customInputsLink}を使用してログまたはメトリックを収集するか、{beatsTutorialLink}を使用してデータを追加してください。{discussForumLink}を使用して新しい統合を要求してください。", "xpack.fleet.integrations.packageInstallErrorDescription": "このパッケージのインストール中に問題が発生しました。しばらくたってから再試行してください。", "xpack.fleet.integrations.packageInstallErrorTitle": "{title}パッケージをインストールできませんでした", "xpack.fleet.integrations.packageInstallSuccessDescription": "正常に{title}をインストールしました", @@ -10879,8 +10869,6 @@ "xpack.fleet.integrations.updatePackage.updatePackageButtonLabel": "最新バージョンに更新", "xpack.fleet.integrationsAppTitle": "統合", "xpack.fleet.integrationsHeaderTitle": "Elasticエージェント統合", - "xpack.fleet.integrationsPermissionDeniedErrorMessage": "統合にアクセスする権限がありません。統合には{roleName}権限が必要です。", - "xpack.fleet.integrationsSecurityRequiredErrorMessage": "統合を使用するには、KibanaとElasticsearchでセキュリティを有効にする必要があります。", "xpack.fleet.invalidLicenseDescription": "現在のライセンスは期限切れです。登録されたビートエージェントは引き続き動作しますが、Elastic Fleet インターフェイスにアクセスするには有効なライセンスが必要です。", "xpack.fleet.invalidLicenseTitle": "ライセンスの期限切れ", "xpack.fleet.multiTextInput.addRow": "行の追加", @@ -10952,8 +10940,6 @@ "xpack.fleet.preconfiguration.missingIDError": "{agentPolicyName}には「id」フィールドがありません。ポリシーのis_defaultまたはis_default_fleet_serverに設定されている場合をのぞき、「id」は必須です。", "xpack.fleet.preconfiguration.packageMissingError": "{agentPolicyName}を追加できませんでした。{pkgName}がインストールされていません。{pkgName}を`{packagesConfigValue}`に追加するか、{packagePolicyName}から削除してください。", "xpack.fleet.preconfiguration.policyDeleted": "構成済みのポリシー{id}が削除されました。作成をスキップしています", - "xpack.fleet.securityRequiredErrorMessage": "Fleet を使用するには、Kibana と Elasticsearch でセキュリティを有効にする必要があります。", - "xpack.fleet.securityRequiredErrorTitle": "セキュリティが有効ではありません", "xpack.fleet.serverError.agentPolicyDoesNotExist": "エージェントポリシー{agentPolicyId}が存在しません", "xpack.fleet.serverError.enrollmentKeyDuplicate": "エージェントポリシーの{agentPolicyId}登録キー{providedKeyName}はすでに存在します", "xpack.fleet.serverError.returnedIncorrectKey": "find enrollmentKeyByIdで正しくないキーが返されました", @@ -22174,7 +22160,6 @@ "xpack.securitySolution.enpdoint.resolver.panelutils.invaliddate": "無効な日付", "xpack.securitySolution.enpdoint.resolver.panelutils.noTimestampRetrieved": "タイムスタンプが取得されていません", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "Endpoint Securityで開く", - "xpack.securitySolution.event.reason.eventRenderPopoverTitle": "イベントレンダラー:{eventRendererName} ", "xpack.securitySolution.eventDetails.blank": " ", "xpack.securitySolution.eventDetails.copyToClipboard": "クリップボードにコピー", "xpack.securitySolution.eventDetails.copyToClipboardTooltip": "クリップボードにコピー", @@ -24437,8 +24422,6 @@ "xpack.timelines.hoverActions.addToTimeline.addedFieldMessage": "{fieldOrValue}をタイムラインに追加しました", "xpack.timelines.hoverActions.columnToggleLabel": "表の{field}列を切り替える", "xpack.timelines.hoverActions.fieldLabel": "フィールド", - "xpack.timelines.hoverActions.filterForValue": "値でフィルター", - "xpack.timelines.hoverActions.filterOutValue": "値を除外", "xpack.timelines.hoverActions.moreActions": "さらにアクションを表示", "xpack.timelines.hoverActions.nestedColumnToggleLabel": "{field}フィールドはオブジェクトであり、列として追加できるネストされたフィールドに分解されます", "xpack.timelines.hoverActions.tooltipWithKeyboardShortcut.pressTooltipLabel": "プレス", @@ -25052,7 +25035,6 @@ "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.unableToGetChoicesMessage": "選択肢を取得できません", "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.urgencySelectFieldLabel": "緊急", "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.usernameTextFieldLabel": "ユーザー名", - "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowAction.apiUrlHelpLabel": "Personal Developer Instance の構成", "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowITSM.actionTypeTitle": "ServiceNow ITSM", "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowITSM.selectMessageText": "ServiceNow ITSMでインシデントを作成します。", "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowSIR.actionTypeTitle": "ServiceNow SecOps", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4d86994c0fb84..1271e3a32a0d3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1180,8 +1180,6 @@ "core.euiLink.external.ariaLabel": "外部链接", "core.euiLink.newTarget.screenReaderOnlyText": "(在新选项卡或窗口中打开)", "core.euiMarkdownEditorFooter.closeButton": "关闭", - "core.euiMarkdownEditorFooter.descriptionPrefix": "此编辑器使用", - "core.euiMarkdownEditorFooter.descriptionSuffix": "还可以利用这些附加的语法插件向文本添加富文本内容。", "core.euiMarkdownEditorFooter.errorsTitle": "错误", "core.euiMarkdownEditorFooter.openUploadModal": "打开上传文件模式窗口", "core.euiMarkdownEditorFooter.showMarkdownHelp": "显示 Markdown 帮助", @@ -3021,13 +3019,11 @@ "home.tutorial.card.sampleDataDescription": "开始使用这些“一键式”数据集浏览 Kibana。", "home.tutorial.card.sampleDataTitle": "样例数据", "home.tutorial.elasticCloudButtonLabel": "Elastic Cloud", - "home.tutorial.instruction.copyButtonLabel": "复制代码片段", "home.tutorial.instructionSet.checkStatusButtonLabel": "检查状态", "home.tutorial.instructionSet.customizeLabel": "定制您的代码片段", "home.tutorial.instructionSet.noDataLabel": "未找到任何数据", "home.tutorial.instructionSet.statusCheckTitle": "状态检查", "home.tutorial.instructionSet.successLabel": "成功", - "home.tutorial.instructionSet.toggleAriaLabel": "切换命令参数可见性", "home.tutorial.introduction.betaLabel": "公测版", "home.tutorial.introduction.imageAltDescription": "主仪表板的截图。", "home.tutorial.introduction.viewButtonLabel": "查看导出的字段", @@ -4957,6 +4953,16 @@ "visTypeMetric.colorModes.backgroundOptionLabel": "背景", "visTypeMetric.colorModes.labelsOptionLabel": "标签", "visTypeMetric.colorModes.noneOptionLabel": "无", + "visTypeMetric.metricDescription": "将计算结果显示为单个数字。", + "visTypeMetric.metricTitle": "指标", + "visTypeMetric.params.color.useForLabel": "将颜色用于", + "visTypeMetric.params.rangesTitle": "范围", + "visTypeMetric.params.settingsTitle": "设置", + "visTypeMetric.params.showTitleLabel": "显示标题", + "visTypeMetric.params.style.fontSizeLabel": "指标字体大小(磅)", + "visTypeMetric.params.style.styleTitle": "样式", + "visTypeMetric.schemas.metricTitle": "指标", + "visTypeMetric.schemas.splitGroupTitle": "拆分组", "expressionMetricVis.function.dimension.splitGroup": "拆分组", "expressionMetricVis.function.bgFill.help": "将颜色表示为 html 十六进制代码 (#123456)、html 颜色(red、blue)或 rgba 值 (rgba(255,255,255,1))。", "expressionMetricVis.function.bucket.help": "存储桶维度配置", @@ -4972,16 +4978,6 @@ "expressionMetricVis.function.showLabels.help": "在指标值下显示标签。", "expressionMetricVis.function.subText.help": "要在指标下显示的定制文本", "expressionMetricVis.function.useRanges.help": "已启用颜色范围。", - "visTypeMetric.metricDescription": "将计算结果显示为单个数字。", - "visTypeMetric.metricTitle": "指标", - "visTypeMetric.params.color.useForLabel": "将颜色用于", - "visTypeMetric.params.rangesTitle": "范围", - "visTypeMetric.params.settingsTitle": "设置", - "visTypeMetric.params.showTitleLabel": "显示标题", - "visTypeMetric.params.style.fontSizeLabel": "指标字体大小(磅)", - "visTypeMetric.params.style.styleTitle": "样式", - "visTypeMetric.schemas.metricTitle": "指标", - "visTypeMetric.schemas.splitGroupTitle": "拆分组", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.deprecation": "Visualize 中饼图的旧版图表库已弃用,自 8.0 后将不受支持。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.description": "在 Visualize 中启用饼图的旧版图表库。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.name": "饼图旧版图表库", @@ -6963,7 +6959,6 @@ "xpack.apm.tutorial.apmServer.statusCheck.text": "在开始实施 APM 代理之前,确保 APM Server 正在运行。", "xpack.apm.tutorial.apmServer.statusCheck.title": "APM Server 状态", "xpack.apm.tutorial.apmServer.title": "APM Server", - "xpack.apm.tutorial.copySnippet": "复制代码片段", "xpack.apm.tutorial.djangoClient.configure.commands.addAgentComment": "向已安装应用添加代理", "xpack.apm.tutorial.djangoClient.configure.commands.addTracingMiddlewareComment": "要发送性能指标,请添加我们的跟踪中间件:", "xpack.apm.tutorial.djangoClient.configure.commands.allowedCharactersComment": "a-z、A-Z、0-9、-、_ 以及空格", @@ -10839,7 +10834,6 @@ "xpack.fleet.epm.detailsTitle": "详情", "xpack.fleet.epm.errorLoadingNotice": "加载 NOTICE.txt 时出错", "xpack.fleet.epm.featuresLabel": "功能", - "xpack.fleet.epm.illustrationAltText": "集成的图示", "xpack.fleet.epm.install.packageInstallError": "安装 {pkgName} {pkgVersion} 时出错", "xpack.fleet.epm.install.packageUpdateError": "将 {pkgName} 更新到 {pkgVersion} 时出错", "xpack.fleet.epm.licenseLabel": "许可证", @@ -10862,7 +10856,6 @@ "xpack.fleet.epm.packageDetailsNav.packageCustomLinkText": "高级", "xpack.fleet.epm.packageDetailsNav.packagePoliciesLinkText": "策略", "xpack.fleet.epm.packageDetailsNav.settingsLinkText": "设置", - "xpack.fleet.epm.pageSubtitle": "使用 Elastic 代理从热门应用和服务中收集数据", "xpack.fleet.epm.releaseBadge.betaDescription": "在生产环境中不推荐使用此集成。", "xpack.fleet.epm.releaseBadge.betaLabel": "公测版", "xpack.fleet.epm.releaseBadge.experimentalDescription": "此集成可能有重大更改或将在未来版本中移除。", @@ -10875,7 +10868,6 @@ "xpack.fleet.epm.usedByLabel": "代理策略", "xpack.fleet.epm.versionLabel": "版本", "xpack.fleet.epmList.allPackagesFilterLinkText": "全部", - "xpack.fleet.epmList.allTitle": "按类别浏览", "xpack.fleet.epmList.installedTitle": "已安装集成", "xpack.fleet.epmList.missingIntegrationPlaceholder": "我们未找到任何匹配搜索词的集成。请重试其他关键字,或使用左侧的类别浏览。", "xpack.fleet.epmList.noPackagesFoundPlaceholder": "未找到任何软件包", @@ -10949,12 +10941,10 @@ "xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注意:", "xpack.fleet.hostsInput.addRow": "添加行", "xpack.fleet.initializationErrorMessageTitle": "无法初始化 Fleet", - "xpack.fleet.integrations.beatsModulesLink": "Beats 模板", "xpack.fleet.integrations.customInputsLink": "定制输入", "xpack.fleet.integrations.discussForumLink": "讨论论坛", "xpack.fleet.integrations.installPackage.installingPackageButtonLabel": "正在安装 {title} 资产", "xpack.fleet.integrations.installPackage.installPackageButtonLabel": "安装 {title} 资产", - "xpack.fleet.integrations.missing": "未看到集成?使用我们的{customInputsLink}收集任何日志或指标或使用 {beatsTutorialLink} 添加数据。使用{discussForumLink}请求新的集成。", "xpack.fleet.integrations.packageInstallErrorDescription": "尝试安装此软件包时出现问题。请稍后重试。", "xpack.fleet.integrations.packageInstallErrorTitle": "无法安装 {title} 软件包", "xpack.fleet.integrations.packageInstallSuccessDescription": "已成功安装 {title}", @@ -10993,8 +10983,6 @@ "xpack.fleet.integrations.updatePackage.updatePackageButtonLabel": "更新到最新版本", "xpack.fleet.integrationsAppTitle": "集成", "xpack.fleet.integrationsHeaderTitle": "Elastic 代理集成", - "xpack.fleet.integrationsPermissionDeniedErrorMessage": "您无权访问“集成”。“集成”需要 {roleName} 权限。", - "xpack.fleet.integrationsSecurityRequiredErrorMessage": "必须在 Kibana 和 Elasticsearch 中启用安全性,才能使用“集成”。", "xpack.fleet.invalidLicenseDescription": "您当前的许可证已过期。已注册 Beats 代理将继续工作,但您需要有效的许可证,才能访问 Elastic Fleet 界面。", "xpack.fleet.invalidLicenseTitle": "已过期许可证", "xpack.fleet.multiTextInput.addRow": "添加行", @@ -11066,8 +11054,6 @@ "xpack.fleet.preconfiguration.missingIDError": "{agentPolicyName} 缺失 `id` 字段。`id` 是必需的,但标记为 is_default 或 is_default_fleet_server 的策略除外。", "xpack.fleet.preconfiguration.packageMissingError": "{agentPolicyName} 无法添加。{pkgName} 未安装,请将 {pkgName} 添加到 `{packagesConfigValue}` 或将其从 {packagePolicyName} 中移除。", "xpack.fleet.preconfiguration.policyDeleted": "预配置的策略 {id} 已删除;将跳过创建", - "xpack.fleet.securityRequiredErrorMessage": "必须在 Kibana 和 Elasticsearch 启用安全性,才能使用 Fleet。", - "xpack.fleet.securityRequiredErrorTitle": "安全性未启用", "xpack.fleet.serverError.agentPolicyDoesNotExist": "代理策略 {agentPolicyId} 不存在", "xpack.fleet.serverError.enrollmentKeyDuplicate": "称作 {providedKeyName} 的注册密钥对于代理策略 {agentPolicyId} 已存在", "xpack.fleet.serverError.returnedIncorrectKey": "find enrollmentKeyById 返回错误的密钥", @@ -22522,7 +22508,6 @@ "xpack.securitySolution.enpdoint.resolver.panelutils.invaliddate": "日期无效", "xpack.securitySolution.enpdoint.resolver.panelutils.noTimestampRetrieved": "未检索时间戳", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "在 Endpoint Security 中打开", - "xpack.securitySolution.event.reason.eventRenderPopoverTitle": "事件渲染器:{eventRendererName} ", "xpack.securitySolution.eventDetails.blank": " ", "xpack.securitySolution.eventDetails.copyToClipboard": "复制到剪贴板", "xpack.securitySolution.eventDetails.copyToClipboardTooltip": "复制到剪贴板", @@ -24850,8 +24835,6 @@ "xpack.timelines.hoverActions.addToTimeline.addedFieldMessage": "已将 {fieldOrValue} 添加到时间线", "xpack.timelines.hoverActions.columnToggleLabel": "在表中切换 {field} 列", "xpack.timelines.hoverActions.fieldLabel": "字段", - "xpack.timelines.hoverActions.filterForValue": "筛留值", - "xpack.timelines.hoverActions.filterOutValue": "筛除值", "xpack.timelines.hoverActions.moreActions": "更多操作", "xpack.timelines.hoverActions.nestedColumnToggleLabel": "{field} 字段是对象,并分解为可以添加为列的嵌套字段", "xpack.timelines.hoverActions.tooltipWithKeyboardShortcut.pressTooltipLabel": "按", @@ -25480,7 +25463,6 @@ "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.unableToGetChoicesMessage": "无法获取选项", "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.urgencySelectFieldLabel": "紧急性", "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.usernameTextFieldLabel": "用户名", - "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowAction.apiUrlHelpLabel": "配置个人开发者实例", "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowITSM.actionTypeTitle": "ServiceNow ITSM", "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowITSM.selectMessageText": "在 ServiceNow ITSM 中创建事件。", "xpack.triggersActionsUI.components.builtinActionTypes.serviceNowSIR.actionTypeTitle": "ServiceNow SecOps", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx index 0b446b99c93dc..a96e1fc3dcb5d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx @@ -35,6 +35,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="emailFromInput"]').length > 0).toBeTruthy(); @@ -66,6 +68,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="emailFromInput"]').length > 0).toBeTruthy(); @@ -99,6 +103,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="emailFromInput"]').first().prop('value')).toBe( @@ -132,6 +138,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="emailServiceSelectInput"]').length > 0).toBeTruthy(); @@ -165,6 +173,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="emailHostInput"]').first().prop('disabled')).toBe(true); @@ -199,6 +209,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="emailHostInput"]').first().prop('disabled')).toBe(false); @@ -223,6 +235,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -245,6 +259,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); @@ -268,6 +284,8 @@ describe('EmailActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx index e804ce2a9f54d..9ef498334ad3d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx @@ -71,6 +71,8 @@ describe('IndexActionConnectorFields renders', () => { editActionSecrets: () => {}, errors: { index: [] }, readOnly: false, + setCallbacks: () => {}, + isEdit: false, }; const wrapper = mountWithIntl(<IndexActionConnectorFields {...props} />); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx index be5250ccf8b29..4859c25adcc06 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx @@ -34,6 +34,8 @@ describe('JiraActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -74,6 +76,8 @@ describe('JiraActionConnectorFields renders', () => { editActionSecrets={() => {}} readOnly={false} consumer={'case'} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="apiUrlFromInput"]').length > 0).toBeTruthy(); @@ -104,6 +108,8 @@ describe('JiraActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -125,6 +131,8 @@ describe('JiraActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); @@ -152,6 +160,8 @@ describe('JiraActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx index 86347de528a01..8be15ddaa6bca 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx @@ -33,6 +33,8 @@ describe('PagerDutyActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -61,6 +63,8 @@ describe('PagerDutyActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -86,6 +90,8 @@ describe('PagerDutyActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); @@ -112,6 +118,8 @@ describe('PagerDutyActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx index bbd237a7cec89..35891f513be6b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx @@ -34,6 +34,8 @@ describe('ResilientActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -74,6 +76,8 @@ describe('ResilientActionConnectorFields renders', () => { editActionSecrets={() => {}} readOnly={false} consumer={'case'} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -105,6 +109,8 @@ describe('ResilientActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -126,6 +132,8 @@ describe('ResilientActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); @@ -153,6 +161,8 @@ describe('ResilientActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.test.ts index ba820efc8111f..4b67d256d99bc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.test.ts @@ -6,7 +6,7 @@ */ import { httpServiceMock } from '../../../../../../../../src/core/public/mocks'; -import { getChoices } from './api'; +import { getChoices, getAppInfo } from './api'; const choicesResponse = { status: 'ok', @@ -44,10 +44,27 @@ const choicesResponse = { ], }; +const applicationInfoData = { + result: { name: 'Elastic', scope: 'x_elas2_inc_int', version: '1.0.0' }, +}; + +const applicationInfoResponse = { + ok: true, + status: 200, + json: async () => applicationInfoData, +}; + describe('ServiceNow API', () => { const http = httpServiceMock.createStartContract(); + let fetchMock: jest.SpyInstance<Promise<unknown>>; - beforeEach(() => jest.resetAllMocks()); + beforeAll(() => { + fetchMock = jest.spyOn(window, 'fetch'); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); describe('getChoices', () => { test('should call get choices API', async () => { @@ -67,4 +84,96 @@ describe('ServiceNow API', () => { }); }); }); + + describe('getAppInfo', () => { + test('should call getAppInfo API for ITSM', async () => { + const abortCtrl = new AbortController(); + fetchMock.mockResolvedValueOnce(applicationInfoResponse); + + const res = await getAppInfo({ + signal: abortCtrl.signal, + apiUrl: 'https://example.com', + username: 'test', + password: 'test', + actionTypeId: '.servicenow', + }); + + expect(res).toEqual(applicationInfoData.result); + expect(fetchMock).toHaveBeenCalledWith( + 'https://example.com/api/x_elas2_inc_int/elastic_api/health', + { + signal: abortCtrl.signal, + method: 'GET', + headers: { Authorization: 'Basic dGVzdDp0ZXN0' }, + } + ); + }); + + test('should call getAppInfo API correctly for SIR', async () => { + const abortCtrl = new AbortController(); + fetchMock.mockResolvedValueOnce(applicationInfoResponse); + + const res = await getAppInfo({ + signal: abortCtrl.signal, + apiUrl: 'https://example.com', + username: 'test', + password: 'test', + actionTypeId: '.servicenow-sir', + }); + + expect(res).toEqual(applicationInfoData.result); + expect(fetchMock).toHaveBeenCalledWith( + 'https://example.com/api/x_elas2_sir_int/elastic_api/health', + { + signal: abortCtrl.signal, + method: 'GET', + headers: { Authorization: 'Basic dGVzdDp0ZXN0' }, + } + ); + }); + + it('returns an error when the response fails', async () => { + expect.assertions(1); + + const abortCtrl = new AbortController(); + fetchMock.mockResolvedValueOnce({ + ok: false, + status: 401, + json: async () => applicationInfoResponse.json, + }); + + await expect(() => + getAppInfo({ + signal: abortCtrl.signal, + apiUrl: 'https://example.com', + username: 'test', + password: 'test', + actionTypeId: '.servicenow', + }) + ).rejects.toThrow('Received status:'); + }); + + it('returns an error when parsing the json fails', async () => { + expect.assertions(1); + + const abortCtrl = new AbortController(); + fetchMock.mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => { + throw new Error('bad'); + }, + }); + + await expect(() => + getAppInfo({ + signal: abortCtrl.signal, + apiUrl: 'https://example.com', + username: 'test', + password: 'test', + actionTypeId: '.servicenow', + }) + ).rejects.toThrow('bad'); + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts index 62347580e75ca..32a2d0296d4c9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts @@ -6,7 +6,11 @@ */ import { HttpSetup } from 'kibana/public'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { snExternalServiceConfig } from '../../../../../../actions/server/builtin_action_types/servicenow/config'; import { BASE_ACTION_API_PATH } from '../../../constants'; +import { API_INFO_ERROR } from './translations'; +import { AppInfo, RESTApiError } from './types'; export async function getChoices({ http, @@ -29,3 +33,43 @@ export async function getChoices({ } ); } + +/** + * The app info url should be the same as at: + * x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts + */ +const getAppInfoUrl = (url: string, scope: string) => `${url}/api/${scope}/elastic_api/health`; + +export async function getAppInfo({ + signal, + apiUrl, + username, + password, + actionTypeId, +}: { + signal: AbortSignal; + apiUrl: string; + username: string; + password: string; + actionTypeId: string; +}): Promise<AppInfo | RESTApiError> { + const urlWithoutTrailingSlash = apiUrl.endsWith('/') ? apiUrl.slice(0, -1) : apiUrl; + const config = snExternalServiceConfig[actionTypeId]; + const response = await fetch(getAppInfoUrl(urlWithoutTrailingSlash, config.appScope ?? ''), { + method: 'GET', + signal, + headers: { + Authorization: 'Basic ' + btoa(username + ':' + password), + }, + }); + + if (!response.ok) { + throw new Error(API_INFO_ERROR(response.status)); + } + + const data = await response.json(); + + return { + ...data.result, + }; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx new file mode 100644 index 0000000000000..67c3238b04774 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { ApplicationRequiredCallout } from './application_required_callout'; + +describe('ApplicationRequiredCallout', () => { + test('it renders the callout', () => { + render(<ApplicationRequiredCallout />); + expect(screen.getByText('Elastic ServiceNow App not installed')).toBeInTheDocument(); + expect( + screen.getByText('Please go to the ServiceNow app store and install the application') + ).toBeInTheDocument(); + }); + + test('it renders the ServiceNow store button', () => { + render(<ApplicationRequiredCallout />); + expect(screen.getByText('Visit ServiceNow app store')).toBeInTheDocument(); + }); + + test('it renders an error message if provided', () => { + render(<ApplicationRequiredCallout message="Denied" />); + expect(screen.getByText('Error message: Denied')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.tsx new file mode 100644 index 0000000000000..561dae95fe1b7 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.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, { memo } from 'react'; +import { EuiSpacer, EuiCallOut } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { SNStoreButton } from './sn_store_button'; + +const content = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.applicationRequiredCallout.content', + { + defaultMessage: 'Please go to the ServiceNow app store and install the application', + } +); + +const ERROR_MESSAGE = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.applicationRequiredCallout.errorMessage', + { + defaultMessage: 'Error message', + } +); + +interface Props { + message?: string | null; +} + +const ApplicationRequiredCalloutComponent: React.FC<Props> = ({ message }) => { + return ( + <> + <EuiSpacer size="s" /> + <EuiCallOut + size="m" + iconType="alert" + data-test-subj="snDeprecatedCallout" + color="danger" + title={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.applicationRequiredCallout', + { + defaultMessage: 'Elastic ServiceNow App not installed', + } + )} + > + <p>{content}</p> + {message && ( + <p> + {ERROR_MESSAGE}: {message} + </p> + )} + <SNStoreButton color="danger" /> + </EuiCallOut> + <EuiSpacer size="m" /> + </> + ); +}; + +export const ApplicationRequiredCallout = memo(ApplicationRequiredCalloutComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts new file mode 100644 index 0000000000000..9d5fafbf5a0ea --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.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 const UPDATE_INCIDENT_VARIABLE = '{{rule.id}}'; +export const NOT_UPDATE_INCIDENT_VARIABLE = '{{rule.id}}:{{alert.id}}'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/credentials.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/credentials.tsx new file mode 100644 index 0000000000000..caee946524265 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/credentials.tsx @@ -0,0 +1,191 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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, useCallback } from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiLink, + EuiFieldText, + EuiSpacer, + EuiTitle, + EuiFieldPassword, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { ActionConnectorFieldsProps } from '../../../../../public/types'; +import { useKibana } from '../../../../common/lib/kibana'; +import { getEncryptedFieldNotifyLabel } from '../../get_encrypted_field_notify_label'; +import * as i18n from './translations'; +import { ServiceNowActionConnector } from './types'; +import { isFieldInvalid } from './helpers'; + +interface Props { + action: ActionConnectorFieldsProps<ServiceNowActionConnector>['action']; + errors: ActionConnectorFieldsProps<ServiceNowActionConnector>['errors']; + readOnly: boolean; + isLoading: boolean; + editActionSecrets: ActionConnectorFieldsProps<ServiceNowActionConnector>['editActionSecrets']; + editActionConfig: ActionConnectorFieldsProps<ServiceNowActionConnector>['editActionConfig']; +} + +const CredentialsComponent: React.FC<Props> = ({ + action, + errors, + readOnly, + isLoading, + editActionSecrets, + editActionConfig, +}) => { + const { docLinks } = useKibana().services; + const { apiUrl } = action.config; + const { username, password } = action.secrets; + + const isApiUrlInvalid = isFieldInvalid(apiUrl, errors.apiUrl); + const isUsernameInvalid = isFieldInvalid(username, errors.username); + const isPasswordInvalid = isFieldInvalid(password, errors.password); + + const handleOnChangeActionConfig = useCallback( + (key: string, value: string) => editActionConfig(key, value), + [editActionConfig] + ); + + const handleOnChangeSecretConfig = useCallback( + (key: string, value: string) => editActionSecrets(key, value), + [editActionSecrets] + ); + + return ( + <> + <EuiFlexGroup direction="column"> + <EuiFlexItem> + <EuiTitle size="xxs"> + <h4>{i18n.SN_INSTANCE_LABEL}</h4> + </EuiTitle> + <p> + <FormattedMessage + id="xpack.triggersActionsUI.components.builtinActionTypes.serviceNowAction.apiUrlHelpLabel" + defaultMessage="Please provide the full URL to the desired ServiceNow instance. If you do not have one, you can {instance}" + values={{ + instance: ( + <EuiLink href={docLinks.links.alerting.serviceNowAction} target="_blank"> + {i18n.SETUP_DEV_INSTANCE} + </EuiLink> + ), + }} + /> + </p> + </EuiFlexItem> + <EuiFlexItem> + <EuiFormRow + id="apiUrl" + fullWidth + error={errors.apiUrl} + isInvalid={isApiUrlInvalid} + label={i18n.API_URL_LABEL} + helpText={i18n.API_URL_HELPTEXT} + > + <EuiFieldText + fullWidth + isInvalid={isApiUrlInvalid} + name="apiUrl" + readOnly={readOnly} + value={apiUrl || ''} // Needed to prevent uncontrolled input error when value is undefined + data-test-subj="apiUrlFromInput" + onChange={(evt) => handleOnChangeActionConfig('apiUrl', evt.target.value)} + onBlur={() => { + if (!apiUrl) { + editActionConfig('apiUrl', ''); + } + }} + disabled={isLoading} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer size="m" /> + <EuiFlexGroup> + <EuiFlexItem> + <EuiTitle size="xxs"> + <h4>{i18n.AUTHENTICATION_LABEL}</h4> + </EuiTitle> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer size="m" /> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow fullWidth> + {getEncryptedFieldNotifyLabel( + !action.id, + 2, + action.isMissingSecrets ?? false, + i18n.REENTER_VALUES_LABEL + )} + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer size="m" /> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow + id="connector-servicenow-username" + fullWidth + error={errors.username} + isInvalid={isUsernameInvalid} + label={i18n.USERNAME_LABEL} + > + <EuiFieldText + fullWidth + isInvalid={isUsernameInvalid} + readOnly={readOnly} + name="connector-servicenow-username" + value={username || ''} // Needed to prevent uncontrolled input error when value is undefined + data-test-subj="connector-servicenow-username-form-input" + onChange={(evt) => handleOnChangeSecretConfig('username', evt.target.value)} + onBlur={() => { + if (!username) { + editActionSecrets('username', ''); + } + }} + disabled={isLoading} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer size="m" /> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow + id="connector-servicenow-password" + fullWidth + error={errors.password} + isInvalid={isPasswordInvalid} + label={i18n.PASSWORD_LABEL} + > + <EuiFieldPassword + fullWidth + readOnly={readOnly} + isInvalid={isPasswordInvalid} + name="connector-servicenow-password" + value={password || ''} // Needed to prevent uncontrolled input error when value is undefined + data-test-subj="connector-servicenow-password-form-input" + onChange={(evt) => handleOnChangeSecretConfig('password', evt.target.value)} + onBlur={() => { + if (!password) { + editActionSecrets('password', ''); + } + }} + disabled={isLoading} + /> + </EuiFormRow> + </EuiFlexItem> + </EuiFlexGroup> + </> + ); +}; + +export const Credentials = memo(CredentialsComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/deprecated_callout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/deprecated_callout.test.tsx new file mode 100644 index 0000000000000..767b38ebcf6ad --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/deprecated_callout.test.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { I18nProvider } from '@kbn/i18n/react'; + +import { DeprecatedCallout } from './deprecated_callout'; + +describe('DeprecatedCallout', () => { + const onMigrate = jest.fn(); + + test('it renders correctly', () => { + render(<DeprecatedCallout onMigrate={onMigrate} />, { + wrapper: ({ children }) => <I18nProvider>{children}</I18nProvider>, + }); + + expect(screen.getByText('Deprecated connector type')).toBeInTheDocument(); + }); + + test('it calls onMigrate when pressing the button', () => { + render(<DeprecatedCallout onMigrate={onMigrate} />, { + wrapper: ({ children }) => <I18nProvider>{children}</I18nProvider>, + }); + + const button = screen.getByRole('button'); + fireEvent.click(button); + + expect(onMigrate).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/deprecated_callout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/deprecated_callout.tsx new file mode 100644 index 0000000000000..101d1572a67ad --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/deprecated_callout.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiSpacer, EuiCallOut, EuiButtonEmpty } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +interface Props { + onMigrate: () => void; +} + +const DeprecatedCalloutComponent: React.FC<Props> = ({ onMigrate }) => { + return ( + <> + <EuiSpacer size="s" /> + <EuiCallOut + size="m" + iconType="alert" + data-test-subj="snDeprecatedCallout" + color="warning" + title={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.deprecatedCalloutTitle', + { + defaultMessage: 'Deprecated connector type', + } + )} + > + <FormattedMessage + defaultMessage="This connector type is deprecated. Create a new connector or {migrate}" + id="xpack.triggersActionsUI.components.builtinActionTypes.servicenow.appInstallationInfo" + values={{ + migrate: ( + <EuiButtonEmpty onClick={onMigrate} flush="left"> + {i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.deprecatedCalloutMigrate', + { + defaultMessage: 'update this connector.', + } + )} + </EuiButtonEmpty> + ), + }} + /> + </EuiCallOut> + <EuiSpacer size="m" /> + </> + ); +}; + +export const DeprecatedCallout = memo(DeprecatedCalloutComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts new file mode 100644 index 0000000000000..e37d8dd3b4147 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.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 { isRESTApiError, isFieldInvalid } from './helpers'; + +describe('helpers', () => { + describe('isRESTApiError', () => { + const resError = { error: { message: 'error', detail: 'access denied' }, status: '401' }; + + test('should return true if the error is RESTApiError', async () => { + expect(isRESTApiError(resError)).toBeTruthy(); + }); + + test('should return true if there is failure status', async () => { + // @ts-expect-error + expect(isRESTApiError({ status: 'failure' })).toBeTruthy(); + }); + + test('should return false if there is no error', async () => { + // @ts-expect-error + expect(isRESTApiError({ whatever: 'test' })).toBeFalsy(); + }); + }); + + describe('isFieldInvalid', () => { + test('should return true if the field is invalid', async () => { + expect(isFieldInvalid('description', ['required'])).toBeTruthy(); + }); + + test('should return if false the field is not defined', async () => { + expect(isFieldInvalid(undefined, ['required'])).toBeFalsy(); + }); + + test('should return if false the error is not defined', async () => { + // @ts-expect-error + expect(isFieldInvalid('description', undefined)).toBeFalsy(); + }); + + test('should return if false the error is empty', async () => { + expect(isFieldInvalid('description', [])).toBeFalsy(); + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts index 314d224491128..ca557b31c4f4f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts @@ -6,7 +6,38 @@ */ import { EuiSelectOption } from '@elastic/eui'; -import { Choice } from './types'; +import { + ENABLE_NEW_SN_ITSM_CONNECTOR, + ENABLE_NEW_SN_SIR_CONNECTOR, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../actions/server/constants/connectors'; +import { IErrorObject } from '../../../../../public/types'; +import { AppInfo, Choice, RESTApiError, ServiceNowActionConnector } from './types'; export const choicesToEuiOptions = (choices: Choice[]): EuiSelectOption[] => choices.map((choice) => ({ value: choice.value, text: choice.label })); + +export const isRESTApiError = (res: AppInfo | RESTApiError): res is RESTApiError => + (res as RESTApiError).error != null || (res as RESTApiError).status === 'failure'; + +export const isFieldInvalid = ( + field: string | undefined, + error: string | IErrorObject | string[] +): boolean => error !== undefined && error.length > 0 && field !== undefined; + +// TODO: Remove when the applications are certified +export const isLegacyConnector = (connector: ServiceNowActionConnector) => { + if (connector == null) { + return true; + } + + if (!ENABLE_NEW_SN_ITSM_CONNECTOR && connector.actionTypeId === '.servicenow') { + return true; + } + + if (!ENABLE_NEW_SN_SIR_CONNECTOR && connector.actionTypeId === '.servicenow-sir') { + return true; + } + + return connector.config.isLegacy; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx new file mode 100644 index 0000000000000..8e1c1820920c5 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen } from '@testing-library/react'; + +import { InstallationCallout } from './installation_callout'; + +describe('DeprecatedCallout', () => { + test('it renders correctly', () => { + render(<InstallationCallout />); + expect( + screen.getByText( + 'To use this connector, you must first install the Elastic App from the ServiceNow App Store' + ) + ).toBeInTheDocument(); + }); + + test('it renders the button', () => { + render(<InstallationCallout />); + expect(screen.getByRole('link')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.tsx new file mode 100644 index 0000000000000..064207910568f --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiSpacer, EuiCallOut } from '@elastic/eui'; + +import * as i18n from './translations'; +import { SNStoreButton } from './sn_store_button'; + +const InstallationCalloutComponent: React.FC = () => { + return ( + <> + <EuiSpacer size="s" /> + <EuiCallOut + size="m" + iconType="alert" + color="warning" + data-test-subj="snInstallationCallout" + title={i18n.INSTALLATION_CALLOUT_TITLE} + > + <SNStoreButton color="warning" /> + </EuiCallOut> + <EuiSpacer size="m" /> + </> + ); +}; + +export const InstallationCallout = memo(InstallationCalloutComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx index f1516f880dce4..b40db9c2dabda 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -43,6 +43,7 @@ describe('servicenow connector validation', () => { isPreconfigured: false, config: { apiUrl: 'https://dev94428.service-now.com/', + isLegacy: false, }, } as ServiceNowActionConnector; @@ -50,6 +51,7 @@ describe('servicenow connector validation', () => { config: { errors: { apiUrl: [], + isLegacy: [], }, }, secrets: { @@ -77,6 +79,7 @@ describe('servicenow connector validation', () => { config: { errors: { apiUrl: ['URL is required.'], + isLegacy: [], }, }, secrets: { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 24e2a87d42357..bb4a645f10bbc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -27,6 +27,7 @@ const validateConnector = async ( const translations = await import('./translations'); const configErrors = { apiUrl: new Array<string>(), + isLegacy: new Array<string>(), }; const secretsErrors = { username: new Array<string>(), diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx index 4993c51f350ad..02f3ae47728ab 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx @@ -33,6 +33,8 @@ describe('ServiceNowActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect( @@ -57,8 +59,7 @@ describe('ServiceNowActionConnectorFields renders', () => { name: 'servicenow', config: { apiUrl: 'https://test/', - incidentConfiguration: { mapping: [] }, - isCaseOwned: true, + isLegacy: false, }, } as ServiceNowActionConnector; const wrapper = mountWithIntl( @@ -69,6 +70,8 @@ describe('ServiceNowActionConnectorFields renders', () => { editActionSecrets={() => {}} readOnly={false} consumer={'case'} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="apiUrlFromInput"]').length > 0).toBeTruthy(); @@ -91,6 +94,8 @@ describe('ServiceNowActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -112,6 +117,8 @@ describe('ServiceNowActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); @@ -138,6 +145,8 @@ describe('ServiceNowActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 29a6bca4b16ab..2cf738c5e0c13 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -5,162 +5,142 @@ * 2.0. */ -import React, { useCallback } from 'react'; - -import { - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiFieldPassword, - EuiSpacer, - EuiLink, - EuiTitle, -} from '@elastic/eui'; - -import { FormattedMessage } from '@kbn/i18n/react'; +import React, { useCallback, useEffect, useState } from 'react'; + import { ActionConnectorFieldsProps } from '../../../../types'; import * as i18n from './translations'; import { ServiceNowActionConnector } from './types'; import { useKibana } from '../../../../common/lib/kibana'; -import { getEncryptedFieldNotifyLabel } from '../../get_encrypted_field_notify_label'; +import { DeprecatedCallout } from './deprecated_callout'; +import { useGetAppInfo } from './use_get_app_info'; +import { ApplicationRequiredCallout } from './application_required_callout'; +import { isRESTApiError, isLegacyConnector } from './helpers'; +import { InstallationCallout } from './installation_callout'; +import { UpdateConnectorModal } from './update_connector_modal'; +import { updateActionConnector } from '../../../lib/action_connector_api'; +import { Credentials } from './credentials'; const ServiceNowConnectorFields: React.FC<ActionConnectorFieldsProps<ServiceNowActionConnector>> = - ({ action, editActionSecrets, editActionConfig, errors, consumer, readOnly }) => { - const { docLinks } = useKibana().services; + ({ + action, + editActionSecrets, + editActionConfig, + errors, + consumer, + readOnly, + setCallbacks, + isEdit, + }) => { + const { + http, + notifications: { toasts }, + } = useKibana().services; const { apiUrl } = action.config; + const { username, password } = action.secrets; + const isOldConnector = isLegacyConnector(action); - const isApiUrlInvalid: boolean = - errors.apiUrl !== undefined && errors.apiUrl.length > 0 && apiUrl !== undefined; + const [showModal, setShowModal] = useState(false); - const { username, password } = action.secrets; + const { fetchAppInfo, isLoading } = useGetAppInfo({ + actionTypeId: action.actionTypeId, + }); - const isUsernameInvalid: boolean = - errors.username !== undefined && errors.username.length > 0 && username !== undefined; - const isPasswordInvalid: boolean = - errors.password !== undefined && errors.password.length > 0 && password !== undefined; + const [applicationRequired, setApplicationRequired] = useState<boolean>(false); + const [applicationInfoErrorMsg, setApplicationInfoErrorMsg] = useState<string | null>(null); - const handleOnChangeActionConfig = useCallback( - (key: string, value: string) => editActionConfig(key, value), - [editActionConfig] - ); + const getApplicationInfo = useCallback(async () => { + setApplicationRequired(false); + setApplicationInfoErrorMsg(null); + + try { + const res = await fetchAppInfo(action); + if (isRESTApiError(res)) { + throw new Error(res.error?.message ?? i18n.UNKNOWN); + } + + return res; + } catch (e) { + setApplicationRequired(true); + setApplicationInfoErrorMsg(e.message); + // We need to throw here so the connector will be not be saved. + throw e; + } + }, [action, fetchAppInfo]); - const handleOnChangeSecretConfig = useCallback( - (key: string, value: string) => editActionSecrets(key, value), - [editActionSecrets] + const beforeActionConnectorSave = useCallback(async () => { + if (!isOldConnector) { + await getApplicationInfo(); + } + }, [getApplicationInfo, isOldConnector]); + + useEffect( + () => setCallbacks({ beforeActionConnectorSave }), + [beforeActionConnectorSave, setCallbacks] ); + + const onMigrateClick = useCallback(() => setShowModal(true), []); + const onModalCancel = useCallback(() => setShowModal(false), []); + + const onModalConfirm = useCallback(async () => { + await getApplicationInfo(); + await updateActionConnector({ + http, + connector: { + name: action.name, + config: { apiUrl, isLegacy: false }, + secrets: { username, password }, + }, + id: action.id, + }); + + editActionConfig('isLegacy', false); + setShowModal(false); + + toasts.addSuccess({ + title: i18n.MIGRATION_SUCCESS_TOAST_TITLE(action.name), + text: i18n.MIGRATION_SUCCESS_TOAST_TEXT, + }); + }, [ + getApplicationInfo, + http, + action.name, + action.id, + apiUrl, + username, + password, + editActionConfig, + toasts, + ]); + return ( <> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow - id="apiUrl" - fullWidth - error={errors.apiUrl} - isInvalid={isApiUrlInvalid} - label={i18n.API_URL_LABEL} - helpText={ - <EuiLink href={docLinks.links.alerting.serviceNowAction} target="_blank"> - <FormattedMessage - id="xpack.triggersActionsUI.components.builtinActionTypes.serviceNowAction.apiUrlHelpLabel" - defaultMessage="Configure a Personal Developer Instance" - /> - </EuiLink> - } - > - <EuiFieldText - fullWidth - isInvalid={isApiUrlInvalid} - name="apiUrl" - readOnly={readOnly} - value={apiUrl || ''} // Needed to prevent uncontrolled input error when value is undefined - data-test-subj="apiUrlFromInput" - onChange={(evt) => handleOnChangeActionConfig('apiUrl', evt.target.value)} - onBlur={() => { - if (!apiUrl) { - editActionConfig('apiUrl', ''); - } - }} - /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer size="m" /> - <EuiFlexGroup> - <EuiFlexItem> - <EuiTitle size="xxs"> - <h4>{i18n.AUTHENTICATION_LABEL}</h4> - </EuiTitle> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer size="m" /> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow fullWidth> - {getEncryptedFieldNotifyLabel( - !action.id, - 2, - action.isMissingSecrets ?? false, - i18n.REENTER_VALUES_LABEL - )} - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer size="m" /> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow - id="connector-servicenow-username" - fullWidth - error={errors.username} - isInvalid={isUsernameInvalid} - label={i18n.USERNAME_LABEL} - > - <EuiFieldText - fullWidth - isInvalid={isUsernameInvalid} - readOnly={readOnly} - name="connector-servicenow-username" - value={username || ''} // Needed to prevent uncontrolled input error when value is undefined - data-test-subj="connector-servicenow-username-form-input" - onChange={(evt) => handleOnChangeSecretConfig('username', evt.target.value)} - onBlur={() => { - if (!username) { - editActionSecrets('username', ''); - } - }} - /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> - <EuiSpacer size="m" /> - <EuiFlexGroup> - <EuiFlexItem> - <EuiFormRow - id="connector-servicenow-password" - fullWidth - error={errors.password} - isInvalid={isPasswordInvalid} - label={i18n.PASSWORD_LABEL} - > - <EuiFieldPassword - fullWidth - readOnly={readOnly} - isInvalid={isPasswordInvalid} - name="connector-servicenow-password" - value={password || ''} // Needed to prevent uncontrolled input error when value is undefined - data-test-subj="connector-servicenow-password-form-input" - onChange={(evt) => handleOnChangeSecretConfig('password', evt.target.value)} - onBlur={() => { - if (!password) { - editActionSecrets('password', ''); - } - }} - /> - </EuiFormRow> - </EuiFlexItem> - </EuiFlexGroup> + {showModal && ( + <UpdateConnectorModal + action={action} + applicationInfoErrorMsg={applicationInfoErrorMsg} + errors={errors} + readOnly={readOnly} + isLoading={isLoading} + editActionSecrets={editActionSecrets} + editActionConfig={editActionConfig} + onConfirm={onModalConfirm} + onCancel={onModalCancel} + /> + )} + {!isOldConnector && <InstallationCallout />} + {isOldConnector && <DeprecatedCallout onMigrate={onMigrateClick} />} + <Credentials + action={action} + errors={errors} + readOnly={readOnly} + isLoading={isLoading} + editActionSecrets={editActionSecrets} + editActionConfig={editActionConfig} + /> + {applicationRequired && !isOldConnector && ( + <ApplicationRequiredCallout message={applicationInfoErrorMsg} /> + )} </> ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx index e864a8d3fd114..30e09356e95dd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx @@ -31,6 +31,8 @@ const actionParams = { category: 'software', subcategory: 'os', externalId: null, + correlation_id: 'alertID', + correlation_display: 'Alerting', }, comments: [], }, @@ -144,7 +146,10 @@ describe('ServiceNowITSMParamsFields renders', () => { }; mount(<ServiceNowITSMParamsFields {...newProps} />); expect(editAction.mock.calls[0][1]).toEqual({ - incident: {}, + incident: { + correlation_display: 'Alerting', + correlation_id: '{{rule.id}}:{{alert.id}}', + }, comments: [], }); }); @@ -166,7 +171,10 @@ describe('ServiceNowITSMParamsFields renders', () => { wrapper.setProps({ actionConnector: { ...connector, id: '1234' } }); expect(editAction.mock.calls.length).toEqual(1); expect(editAction.mock.calls[0][1]).toEqual({ - incident: {}, + incident: { + correlation_display: 'Alerting', + correlation_id: '{{rule.id}}:{{alert.id}}', + }, comments: [], }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx index b243afb375e6d..81428cd7f0a73 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx @@ -13,16 +13,18 @@ import { EuiFlexItem, EuiSpacer, EuiTitle, + EuiSwitch, } from '@elastic/eui'; import { useKibana } from '../../../../common/lib/kibana'; import { ActionParamsProps } from '../../../../types'; -import { ServiceNowITSMActionParams, Choice, Fields } from './types'; +import { ServiceNowITSMActionParams, Choice, Fields, ServiceNowActionConnector } from './types'; import { TextAreaWithMessageVariables } from '../../text_area_with_message_variables'; import { TextFieldWithMessageVariables } from '../../text_field_with_message_variables'; import { useGetChoices } from './use_get_choices'; -import { choicesToEuiOptions } from './helpers'; +import { choicesToEuiOptions, isLegacyConnector } from './helpers'; import * as i18n from './translations'; +import { UPDATE_INCIDENT_VARIABLE, NOT_UPDATE_INCIDENT_VARIABLE } from './config'; const useGetChoicesFields = ['urgency', 'severity', 'impact', 'category', 'subcategory']; const defaultFields: Fields = { @@ -42,6 +44,8 @@ const ServiceNowParamsFields: React.FunctionComponent< notifications: { toasts }, } = useKibana().services; + const isOldConnector = isLegacyConnector(actionConnector as unknown as ServiceNowActionConnector); + const actionConnectorRef = useRef(actionConnector?.id ?? ''); const { incident, comments } = useMemo( () => @@ -53,8 +57,13 @@ const ServiceNowParamsFields: React.FunctionComponent< [actionParams.subActionParams] ); + const hasUpdateIncident = + incident.correlation_id != null && incident.correlation_id === UPDATE_INCIDENT_VARIABLE; + const [updateIncident, setUpdateIncident] = useState<boolean>(hasUpdateIncident); const [choices, setChoices] = useState<Fields>(defaultFields); + const correlationID = updateIncident ? UPDATE_INCIDENT_VARIABLE : NOT_UPDATE_INCIDENT_VARIABLE; + const editSubActionProperty = useCallback( (key: string, value: any) => { const newProps = @@ -90,6 +99,14 @@ const ServiceNowParamsFields: React.FunctionComponent< ); }, []); + const onUpdateIncidentSwitchChange = useCallback(() => { + const newCorrelationID = !updateIncident + ? UPDATE_INCIDENT_VARIABLE + : NOT_UPDATE_INCIDENT_VARIABLE; + editSubActionProperty('correlation_id', newCorrelationID); + setUpdateIncident(!updateIncident); + }, [editSubActionProperty, updateIncident]); + const categoryOptions = useMemo(() => choicesToEuiOptions(choices.category), [choices.category]); const urgencyOptions = useMemo(() => choicesToEuiOptions(choices.urgency), [choices.urgency]); const severityOptions = useMemo(() => choicesToEuiOptions(choices.severity), [choices.severity]); @@ -119,7 +136,7 @@ const ServiceNowParamsFields: React.FunctionComponent< editAction( 'subActionParams', { - incident: {}, + incident: { correlation_id: correlationID, correlation_display: 'Alerting' }, comments: [], }, index @@ -136,7 +153,7 @@ const ServiceNowParamsFields: React.FunctionComponent< editAction( 'subActionParams', { - incident: {}, + incident: { correlation_id: correlationID, correlation_display: 'Alerting' }, comments: [], }, index @@ -236,25 +253,43 @@ const ServiceNowParamsFields: React.FunctionComponent< </EuiFlexItem> </EuiFlexGroup> <EuiSpacer size="m" /> - <EuiFormRow - fullWidth - error={errors['subActionParams.incident.short_description']} - isInvalid={ - errors['subActionParams.incident.short_description'] !== undefined && - errors['subActionParams.incident.short_description'].length > 0 && - incident.short_description !== undefined - } - label={i18n.SHORT_DESCRIPTION_LABEL} - > - <TextFieldWithMessageVariables - index={index} - editAction={editSubActionProperty} - messageVariables={messageVariables} - paramsProperty={'short_description'} - inputTargetValue={incident?.short_description ?? undefined} - errors={errors['subActionParams.incident.short_description'] as string[]} - /> - </EuiFormRow> + <EuiFlexGroup> + <EuiFlexItem> + <EuiFormRow + fullWidth + error={errors['subActionParams.incident.short_description']} + isInvalid={ + errors['subActionParams.incident.short_description'] !== undefined && + errors['subActionParams.incident.short_description'].length > 0 && + incident.short_description !== undefined + } + label={i18n.SHORT_DESCRIPTION_LABEL} + > + <TextFieldWithMessageVariables + index={index} + editAction={editSubActionProperty} + messageVariables={messageVariables} + paramsProperty={'short_description'} + inputTargetValue={incident?.short_description ?? undefined} + errors={errors['subActionParams.incident.short_description'] as string[]} + /> + </EuiFormRow> + </EuiFlexItem> + {!isOldConnector && ( + <EuiFlexItem> + <EuiFormRow id="update-incident-form-row" fullWidth label={i18n.UPDATE_INCIDENT_LABEL}> + <EuiSwitch + label={updateIncident ? i18n.ON : i18n.OFF} + name="update-incident-switch" + checked={updateIncident} + onChange={onUpdateIncidentSwitchChange} + aria-describedby="update-incident-form-row" + /> + </EuiFormRow> + </EuiFlexItem> + )} + </EuiFlexGroup> + <EuiSpacer size="m" /> <TextAreaWithMessageVariables index={index} editAction={editSubActionProperty} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx index 8637af4cabc94..091b768e2d80d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx @@ -33,6 +33,8 @@ const actionParams = { priority: '1', subcategory: '20', externalId: null, + correlation_id: 'alertID', + correlation_display: 'Alerting', }, comments: [], }, @@ -174,7 +176,10 @@ describe('ServiceNowSIRParamsFields renders', () => { }; mount(<ServiceNowSIRParamsFields {...newProps} />); expect(editAction.mock.calls[0][1]).toEqual({ - incident: {}, + incident: { + correlation_display: 'Alerting', + correlation_id: '{{rule.id}}:{{alert.id}}', + }, comments: [], }); }); @@ -196,7 +201,10 @@ describe('ServiceNowSIRParamsFields renders', () => { wrapper.setProps({ actionConnector: { ...connector, id: '1234' } }); expect(editAction.mock.calls.length).toEqual(1); expect(editAction.mock.calls[0][1]).toEqual({ - incident: {}, + incident: { + correlation_display: 'Alerting', + correlation_id: '{{rule.id}}:{{alert.id}}', + }, comments: [], }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx index 0ba52014fa1f9..7b7cfc67d9971 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx @@ -13,6 +13,7 @@ import { EuiFlexItem, EuiSpacer, EuiTitle, + EuiSwitch, } from '@elastic/eui'; import { useKibana } from '../../../../common/lib/kibana'; import { ActionParamsProps } from '../../../../types'; @@ -21,8 +22,9 @@ import { TextFieldWithMessageVariables } from '../../text_field_with_message_var import * as i18n from './translations'; import { useGetChoices } from './use_get_choices'; -import { ServiceNowSIRActionParams, Fields, Choice } from './types'; -import { choicesToEuiOptions } from './helpers'; +import { ServiceNowSIRActionParams, Fields, Choice, ServiceNowActionConnector } from './types'; +import { choicesToEuiOptions, isLegacyConnector } from './helpers'; +import { UPDATE_INCIDENT_VARIABLE, NOT_UPDATE_INCIDENT_VARIABLE } from './config'; const useGetChoicesFields = ['category', 'subcategory', 'priority']; const defaultFields: Fields = { @@ -31,6 +33,14 @@ const defaultFields: Fields = { priority: [], }; +const valuesToString = (value: string | string[] | null): string | undefined => { + if (Array.isArray(value)) { + return value.join(','); + } + + return value ?? undefined; +}; + const ServiceNowSIRParamsFields: React.FunctionComponent< ActionParamsProps<ServiceNowSIRActionParams> > = ({ actionConnector, actionParams, editAction, index, errors, messageVariables }) => { @@ -39,6 +49,8 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< notifications: { toasts }, } = useKibana().services; + const isOldConnector = isLegacyConnector(actionConnector as unknown as ServiceNowActionConnector); + const actionConnectorRef = useRef(actionConnector?.id ?? ''); const { incident, comments } = useMemo( () => @@ -50,8 +62,13 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< [actionParams.subActionParams] ); + const hasUpdateIncident = + incident.correlation_id != null && incident.correlation_id === UPDATE_INCIDENT_VARIABLE; + const [updateIncident, setUpdateIncident] = useState<boolean>(hasUpdateIncident); const [choices, setChoices] = useState<Fields>(defaultFields); + const correlationID = updateIncident ? UPDATE_INCIDENT_VARIABLE : NOT_UPDATE_INCIDENT_VARIABLE; + const editSubActionProperty = useCallback( (key: string, value: any) => { const newProps = @@ -87,6 +104,14 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< ); }, []); + const onUpdateIncidentSwitchChange = useCallback(() => { + const newCorrelationID = !updateIncident + ? UPDATE_INCIDENT_VARIABLE + : NOT_UPDATE_INCIDENT_VARIABLE; + editSubActionProperty('correlation_id', newCorrelationID); + setUpdateIncident(!updateIncident); + }, [editSubActionProperty, updateIncident]); + const { isLoading: isLoadingChoices } = useGetChoices({ http, toastNotifications: toasts, @@ -115,7 +140,7 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< editAction( 'subActionParams', { - incident: {}, + incident: { correlation_id: correlationID, correlation_display: 'Alerting' }, comments: [], }, index @@ -132,7 +157,7 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< editAction( 'subActionParams', { - incident: {}, + incident: { correlation_id: correlationID, correlation_display: 'Alerting' }, comments: [], }, index @@ -162,48 +187,48 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< editAction={editSubActionProperty} messageVariables={messageVariables} paramsProperty={'short_description'} - inputTargetValue={incident?.short_description ?? undefined} + inputTargetValue={incident?.short_description} errors={errors['subActionParams.incident.short_description'] as string[]} /> </EuiFormRow> <EuiSpacer size="m" /> - <EuiFormRow fullWidth label={i18n.SOURCE_IP_LABEL}> + <EuiFormRow fullWidth label={i18n.SOURCE_IP_LABEL} helpText={i18n.SOURCE_IP_HELP_TEXT}> <TextFieldWithMessageVariables index={index} editAction={editSubActionProperty} messageVariables={messageVariables} paramsProperty={'source_ip'} - inputTargetValue={incident?.source_ip ?? undefined} + inputTargetValue={valuesToString(incident?.source_ip)} /> </EuiFormRow> <EuiSpacer size="m" /> - <EuiFormRow fullWidth label={i18n.DEST_IP_LABEL}> + <EuiFormRow fullWidth label={i18n.DEST_IP_LABEL} helpText={i18n.DEST_IP_HELP_TEXT}> <TextFieldWithMessageVariables index={index} editAction={editSubActionProperty} messageVariables={messageVariables} paramsProperty={'dest_ip'} - inputTargetValue={incident?.dest_ip ?? undefined} + inputTargetValue={valuesToString(incident?.dest_ip)} /> </EuiFormRow> <EuiSpacer size="m" /> - <EuiFormRow fullWidth label={i18n.MALWARE_URL_LABEL}> + <EuiFormRow fullWidth label={i18n.MALWARE_URL_LABEL} helpText={i18n.MALWARE_URL_HELP_TEXT}> <TextFieldWithMessageVariables index={index} editAction={editSubActionProperty} messageVariables={messageVariables} paramsProperty={'malware_url'} - inputTargetValue={incident?.malware_url ?? undefined} + inputTargetValue={valuesToString(incident?.malware_url)} /> </EuiFormRow> <EuiSpacer size="m" /> - <EuiFormRow fullWidth label={i18n.MALWARE_HASH_LABEL}> + <EuiFormRow fullWidth label={i18n.MALWARE_HASH_LABEL} helpText={i18n.MALWARE_HASH_HELP_TEXT}> <TextFieldWithMessageVariables index={index} editAction={editSubActionProperty} messageVariables={messageVariables} paramsProperty={'malware_hash'} - inputTargetValue={incident?.malware_hash ?? undefined} + inputTargetValue={valuesToString(incident?.malware_hash)} /> </EuiFormRow> <EuiSpacer size="m" /> @@ -277,6 +302,18 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< inputTargetValue={comments && comments.length > 0 ? comments[0].comment : undefined} label={i18n.COMMENTS_LABEL} /> + <EuiSpacer size="m" /> + {!isOldConnector && ( + <EuiFormRow id="update-incident-form-row" fullWidth label={i18n.UPDATE_INCIDENT_LABEL}> + <EuiSwitch + label={updateIncident ? i18n.ON : i18n.OFF} + name="update-incident-switch" + checked={updateIncident} + onChange={onUpdateIncidentSwitchChange} + aria-describedby="update-incident-form-row" + /> + </EuiFormRow> + )} </> ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx new file mode 100644 index 0000000000000..fe73653234170 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { SNStoreButton } from './sn_store_button'; + +describe('SNStoreButton', () => { + test('it renders the button', () => { + render(<SNStoreButton color="warning" />); + expect(screen.getByText('Visit ServiceNow app store')).toBeInTheDocument(); + }); + + test('it renders a danger button', () => { + render(<SNStoreButton color="danger" />); + expect(screen.getByRole('link')).toHaveClass('euiButton--danger'); + }); + + test('it renders with correct href', () => { + render(<SNStoreButton color="warning" />); + expect(screen.getByRole('link')).toHaveAttribute('href', 'https://store.servicenow.com/'); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx new file mode 100644 index 0000000000000..5921f679d3f50 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiButtonProps, EuiButton } from '@elastic/eui'; + +import * as i18n from './translations'; + +const STORE_URL = 'https://store.servicenow.com/'; + +interface Props { + color: EuiButtonProps['color']; +} + +const SNStoreButtonComponent: React.FC<Props> = ({ color }) => { + return ( + <EuiButton href={STORE_URL} color={color} iconSide="right" iconType="popout"> + {i18n.VISIT_SN_STORE} + </EuiButton> + ); +}; + +export const SNStoreButton = memo(SNStoreButtonComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts index ea646b896f5e9..90292a35a88df 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts @@ -10,7 +10,14 @@ import { i18n } from '@kbn/i18n'; export const API_URL_LABEL = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiUrlTextFieldLabel', { - defaultMessage: 'URL', + defaultMessage: 'ServiceNow instance URL', + } +); + +export const API_URL_HELPTEXT = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiUrlHelpText', + { + defaultMessage: 'Include the full URL', } ); @@ -53,7 +60,7 @@ export const REMEMBER_VALUES_LABEL = i18n.translate( export const REENTER_VALUES_LABEL = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.reenterValuesLabel', { - defaultMessage: 'Username and password are encrypted. Please reenter values for these fields.', + defaultMessage: 'You will need to re-authenticate each time you edit the connector', } ); @@ -95,14 +102,28 @@ export const TITLE_REQUIRED = i18n.translate( export const SOURCE_IP_LABEL = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.sourceIPTitle', { - defaultMessage: 'Source IP', + defaultMessage: 'Source IPs', + } +); + +export const SOURCE_IP_HELP_TEXT = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.sourceIPHelpText', + { + defaultMessage: 'List of source IPs (comma, or pipe delimited)', } ); export const DEST_IP_LABEL = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.destinationIPTitle', { - defaultMessage: 'Destination IP', + defaultMessage: 'Destination IPs', + } +); + +export const DEST_IP_HELP_TEXT = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.destIPHelpText', + { + defaultMessage: 'List of destination IPs (comma, or pipe delimited)', } ); @@ -137,14 +158,28 @@ export const COMMENTS_LABEL = i18n.translate( export const MALWARE_URL_LABEL = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.malwareURLTitle', { - defaultMessage: 'Malware URL', + defaultMessage: 'Malware URLs', + } +); + +export const MALWARE_URL_HELP_TEXT = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.malwareURLHelpText', + { + defaultMessage: 'List of malware URLs (comma, or pipe delimited)', } ); export const MALWARE_HASH_LABEL = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.malwareHashTitle', { - defaultMessage: 'Malware Hash', + defaultMessage: 'Malware Hashes', + } +); + +export const MALWARE_HASH_HELP_TEXT = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.malwareHashHelpText', + { + defaultMessage: 'List of malware hashes (comma, or pipe delimited)', } ); @@ -196,3 +231,91 @@ export const PRIORITY_LABEL = i18n.translate( defaultMessage: 'Priority', } ); + +export const API_INFO_ERROR = (status: number) => + i18n.translate('xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiInfoError', { + values: { status }, + defaultMessage: 'Received status: {status} when attempting to get application information', + }); + +export const INSTALL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.install', + { + defaultMessage: 'install', + } +); + +export const INSTALLATION_CALLOUT_TITLE = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.installationCalloutTitle', + { + defaultMessage: + 'To use this connector, you must first install the Elastic App from the ServiceNow App Store', + } +); + +export const MIGRATION_SUCCESS_TOAST_TITLE = (connectorName: string) => + i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.migrationSuccessToastTitle', + { + defaultMessage: 'Migrated connector {connectorName}', + values: { + connectorName, + }, + } + ); + +export const MIGRATION_SUCCESS_TOAST_TEXT = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.installationCalloutText', + { + defaultMessage: 'Connector has been successfully migrated.', + } +); + +export const VISIT_SN_STORE = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.visitSNStore', + { + defaultMessage: 'Visit ServiceNow app store', + } +); + +export const SETUP_DEV_INSTANCE = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.setupDevInstance', + { + defaultMessage: 'setup a developer instance', + } +); + +export const SN_INSTANCE_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.snInstanceLabel', + { + defaultMessage: 'ServiceNow instance', + } +); + +export const UNKNOWN = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.unknown', + { + defaultMessage: 'UNKNOWN', + } +); + +export const UPDATE_INCIDENT_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.updateIncidentCheckboxLabel', + { + defaultMessage: 'Update incident', + } +); + +export const ON = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.updateIncidentOn', + { + defaultMessage: 'On', + } +); + +export const OFF = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.updateIncidentOff', + { + defaultMessage: 'Off', + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index f252f4648e670..b24883359dde5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -29,6 +29,7 @@ export interface ServiceNowSIRActionParams { export interface ServiceNowConfig { apiUrl: string; + isLegacy: boolean; } export interface ServiceNowSecrets { @@ -44,3 +45,17 @@ export interface Choice { } export type Fields = Record<string, Choice[]>; +export interface AppInfo { + id: string; + name: string; + scope: string; + version: string; +} + +export interface RESTApiError { + error: { + message: string; + detail: string; + }; + status: string; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector_modal.tsx new file mode 100644 index 0000000000000..b9d660f16dff7 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector_modal.tsx @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiModal, + EuiModalBody, + EuiModalFooter, + EuiModalHeader, + EuiModalHeaderTitle, + EuiCallOut, + EuiTextColor, + EuiHorizontalRule, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ActionConnectorFieldsProps } from '../../../../../public/types'; +import { ServiceNowActionConnector } from './types'; +import { Credentials } from './credentials'; +import { isFieldInvalid } from './helpers'; +import { ApplicationRequiredCallout } from './application_required_callout'; + +const title = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.confirmationModalTitle', + { + defaultMessage: 'Update ServiceNow connector', + } +); + +const cancelButtonText = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.cancelButtonText', + { + defaultMessage: 'Cancel', + } +); + +const confirmButtonText = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.confirmButtonText', + { + defaultMessage: 'Update', + } +); + +const calloutTitle = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.modalCalloutTitle', + { + defaultMessage: + 'The Elastic App from the ServiceNow App Store must be installed prior to running the update.', + } +); + +const warningMessage = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.modalWarningMessage', + { + defaultMessage: 'This will update all instances of this connector. This can not be reversed.', + } +); + +interface Props { + action: ActionConnectorFieldsProps<ServiceNowActionConnector>['action']; + applicationInfoErrorMsg: string | null; + errors: ActionConnectorFieldsProps<ServiceNowActionConnector>['errors']; + isLoading: boolean; + readOnly: boolean; + editActionSecrets: ActionConnectorFieldsProps<ServiceNowActionConnector>['editActionSecrets']; + editActionConfig: ActionConnectorFieldsProps<ServiceNowActionConnector>['editActionConfig']; + onCancel: () => void; + onConfirm: () => void; +} + +const UpdateConnectorModalComponent: React.FC<Props> = ({ + action, + applicationInfoErrorMsg, + errors, + isLoading, + readOnly, + editActionSecrets, + editActionConfig, + onCancel, + onConfirm, +}) => { + const { apiUrl } = action.config; + const { username, password } = action.secrets; + + const hasErrorsOrEmptyFields = + apiUrl === undefined || + username === undefined || + password === undefined || + isFieldInvalid(apiUrl, errors.apiUrl) || + isFieldInvalid(username, errors.username) || + isFieldInvalid(password, errors.password); + + return ( + <EuiModal onClose={onCancel}> + <EuiModalHeader> + <EuiModalHeaderTitle> + <h1>{title}</h1> + </EuiModalHeaderTitle> + </EuiModalHeader> + <EuiModalBody> + <EuiFlexGroup> + <EuiFlexItem> + <EuiCallOut + size="m" + iconType="alert" + data-test-subj="snModalInstallationCallout" + title={calloutTitle} + /> + </EuiFlexItem> + </EuiFlexGroup> + <Credentials + action={action} + errors={errors} + readOnly={readOnly} + isLoading={isLoading} + editActionSecrets={editActionSecrets} + editActionConfig={editActionConfig} + /> + <EuiHorizontalRule /> + <EuiFlexGroup> + <EuiFlexItem> + <EuiTextColor color="danger">{warningMessage}</EuiTextColor> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup> + <EuiFlexItem> + {applicationInfoErrorMsg && ( + <ApplicationRequiredCallout message={applicationInfoErrorMsg} /> + )} + </EuiFlexItem> + </EuiFlexGroup> + </EuiModalBody> + <EuiModalFooter> + <EuiButtonEmpty onClick={onCancel}>{cancelButtonText}</EuiButtonEmpty> + <EuiButton + onClick={onConfirm} + color="danger" + fill + disabled={hasErrorsOrEmptyFields} + isLoading={isLoading} + > + {confirmButtonText} + </EuiButton> + </EuiModalFooter> + </EuiModal> + ); +}; + +export const UpdateConnectorModal = memo(UpdateConnectorModalComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx new file mode 100644 index 0000000000000..c6b70443ec8fb --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook, act } from '@testing-library/react-hooks'; + +import { useGetAppInfo, UseGetAppInfo, UseGetAppInfoProps } from './use_get_app_info'; +import { getAppInfo } from './api'; +import { ServiceNowActionConnector } from './types'; + +jest.mock('./api'); +jest.mock('../../../../common/lib/kibana'); + +const getAppInfoMock = getAppInfo as jest.Mock; + +const actionTypeId = '.servicenow'; +const applicationInfoData = { + name: 'Elastic', + scope: 'x_elas2_inc_int', + version: '1.0.0', +}; + +const actionConnector = { + secrets: { + username: 'user', + password: 'pass', + }, + id: 'test', + actionTypeId: '.servicenow', + name: 'ServiceNow ITSM', + isPreconfigured: false, + config: { + apiUrl: 'https://test.service-now.com/', + isLegacy: false, + }, +} as ServiceNowActionConnector; + +describe('useGetAppInfo', () => { + getAppInfoMock.mockResolvedValue(applicationInfoData); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('init', async () => { + const { result } = renderHook<UseGetAppInfoProps, UseGetAppInfo>(() => + useGetAppInfo({ + actionTypeId, + }) + ); + + expect(result.current).toEqual({ + isLoading: false, + fetchAppInfo: result.current.fetchAppInfo, + }); + }); + + it('returns the application information', async () => { + const { result } = renderHook<UseGetAppInfoProps, UseGetAppInfo>(() => + useGetAppInfo({ + actionTypeId, + }) + ); + + let res; + + await act(async () => { + res = await result.current.fetchAppInfo(actionConnector); + }); + + expect(res).toEqual(applicationInfoData); + }); + + it('it throws an error when api fails', async () => { + expect.assertions(1); + getAppInfoMock.mockImplementation(() => { + throw new Error('An error occurred'); + }); + + const { result } = renderHook<UseGetAppInfoProps, UseGetAppInfo>(() => + useGetAppInfo({ + actionTypeId, + }) + ); + + await expect(() => + act(async () => { + await result.current.fetchAppInfo(actionConnector); + }) + ).rejects.toThrow('An error occurred'); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.tsx new file mode 100644 index 0000000000000..a211c8dda66b7 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState, useEffect, useRef, useCallback } from 'react'; +import { getAppInfo } from './api'; +import { AppInfo, RESTApiError, ServiceNowActionConnector } from './types'; + +export interface UseGetAppInfoProps { + actionTypeId: string; +} + +export interface UseGetAppInfo { + fetchAppInfo: (connector: ServiceNowActionConnector) => Promise<AppInfo | RESTApiError>; + isLoading: boolean; +} + +export const useGetAppInfo = ({ actionTypeId }: UseGetAppInfoProps): UseGetAppInfo => { + const [isLoading, setIsLoading] = useState(false); + const didCancel = useRef(false); + const abortCtrl = useRef(new AbortController()); + + const fetchAppInfo = useCallback( + async (connector) => { + try { + didCancel.current = false; + abortCtrl.current.abort(); + abortCtrl.current = new AbortController(); + setIsLoading(true); + + const res = await getAppInfo({ + signal: abortCtrl.current.signal, + apiUrl: connector.config.apiUrl, + username: connector.secrets.username, + password: connector.secrets.password, + actionTypeId, + }); + + if (!didCancel.current) { + setIsLoading(false); + } + + return res; + } catch (error) { + if (!didCancel.current) { + setIsLoading(false); + } + throw error; + } + }, + [actionTypeId] + ); + + useEffect(() => { + return () => { + didCancel.current = true; + abortCtrl.current.abort(); + setIsLoading(false); + }; + }, []); + + return { + fetchAppInfo, + isLoading, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx index 547346054011b..0a37165bd7f5f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx @@ -30,6 +30,8 @@ describe('SlackActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -56,6 +58,8 @@ describe('SlackActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -76,6 +80,8 @@ describe('SlackActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); @@ -98,6 +104,8 @@ describe('SlackActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/api.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/api.test.ts index 90bab65b83bfd..00262c3265d7a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/api.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/api.test.ts @@ -39,29 +39,28 @@ describe('Swimlane API', () => { }); it('returns an error when the response fails', async () => { + expect.assertions(1); const abortCtrl = new AbortController(); - fetchMock.mockResolvedValueOnce({ ok: false, status: 401, json: async () => getApplicationResponse, }); - try { - await getApplication({ + await expect(() => + getApplication({ signal: abortCtrl.signal, apiToken: '', appId: '', url: '', - }); - } catch (e) { - expect(e.message).toContain('Received status:'); - } + }) + ).rejects.toThrow('Received status:'); }); it('returns an error when parsing the json fails', async () => { - const abortCtrl = new AbortController(); + expect.assertions(1); + const abortCtrl = new AbortController(); fetchMock.mockResolvedValueOnce({ ok: true, status: 200, @@ -70,16 +69,14 @@ describe('Swimlane API', () => { }, }); - try { - await getApplication({ + await expect(() => + getApplication({ signal: abortCtrl.signal, apiToken: '', appId: '', url: '', - }); - } catch (e) { - expect(e.message).toContain('bad'); - } + }) + ).rejects.toThrow('bad'); }); it('it removes unsafe fields', async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_connectors.test.tsx index 6740179d786f2..4829156380e94 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_connectors.test.tsx @@ -50,6 +50,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -77,6 +79,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -106,6 +110,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); @@ -139,6 +145,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -184,6 +192,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -229,6 +239,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -285,6 +297,8 @@ describe('SwimlaneActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams_connectors.test.tsx index 11c747125595d..5031b32281258 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams_connectors.test.tsx @@ -30,6 +30,8 @@ describe('TeamsActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); @@ -56,6 +58,8 @@ describe('TeamsActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -79,6 +83,8 @@ describe('TeamsActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); @@ -103,6 +109,8 @@ describe('TeamsActionFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx index c041b4e3e1e42..ea40c1ddfb139 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx @@ -35,6 +35,8 @@ describe('WebhookActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="webhookViewHeadersSwitch"]').length > 0).toBeTruthy(); @@ -62,6 +64,8 @@ describe('WebhookActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="rememberValuesMessage"]').length).toBeGreaterThan(0); @@ -92,6 +96,8 @@ describe('WebhookActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="reenterValuesMessage"]').length).toBeGreaterThan(0); @@ -123,6 +129,8 @@ describe('WebhookActionConnectorFields renders', () => { editActionConfig={() => {}} editActionSecrets={() => {}} readOnly={false} + setCallbacks={() => {}} + isEdit={false} /> ); expect(wrapper.find('[data-test-subj="missingSecretsMessage"]').length).toBeGreaterThan(0); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index 091ea1e305e35..5a4d682ff573b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -49,6 +49,8 @@ describe('action_connector_form', () => { dispatch={() => {}} errors={{ name: [] }} actionTypeRegistry={actionTypeRegistry} + setCallbacks={() => {}} + isEdit={false} /> ); const connectorNameField = wrapper?.find('[data-test-subj="nameInput"]'); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index f61a0f8f52904..5ee294b6dbd52 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -24,6 +24,7 @@ import { ActionTypeRegistryContract, UserConfiguredActionConnector, ActionTypeModel, + ActionConnectorFieldsSetCallbacks, } from '../../../types'; import { hasSaveActionsCapability } from '../../lib/capabilities'; import { useKibana } from '../../../common/lib/kibana'; @@ -89,6 +90,8 @@ interface ActionConnectorProps< serverError?: { body: { message: string; error: string }; }; + setCallbacks: ActionConnectorFieldsSetCallbacks; + isEdit: boolean; } export const ActionConnectorForm = ({ @@ -99,6 +102,8 @@ export const ActionConnectorForm = ({ errors, actionTypeRegistry, consumer, + setCallbacks, + isEdit, }: ActionConnectorProps) => { const { docLinks, @@ -237,6 +242,8 @@ export const ActionConnectorForm = ({ editActionConfig={setActionConfigProperty} editActionSecrets={setActionSecretsProperty} consumer={consumer} + setCallbacks={setCallbacks} + isEdit={isEdit} /> </Suspense> </EuiErrorBoundary> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 4dcf501fa0023..eda0b99e859a6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -34,11 +34,7 @@ import { ActionTypeForm } from './action_type_form'; import { AddConnectorInline } from './connector_add_inline'; import { actionTypeCompare } from '../../lib/action_type_compare'; import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_enabled'; -import { - VIEW_LICENSE_OPTIONS_LINK, - DEFAULT_HIDDEN_ACTION_TYPES, - DEFAULT_HIDDEN_ONLY_ON_ALERTS_ACTION_TYPES, -} from '../../../common/constants'; +import { VIEW_LICENSE_OPTIONS_LINK, DEFAULT_HIDDEN_ACTION_TYPES } from '../../../common/constants'; import { ActionGroup, AlertActionParam } from '../../../../../alerting/common'; import { useKibana } from '../../../common/lib/kibana'; import { DefaultActionParamsGetter } from '../../lib/get_defaults_for_action_params'; @@ -237,15 +233,9 @@ export const ActionForm = ({ .list() /** * TODO: Remove when cases connector is available across Kibana. Issue: https://github.com/elastic/kibana/issues/82502. - * TODO: Need to decide about ServiceNow SIR connector. * If actionTypes are set, hidden connectors are filtered out. Otherwise, they are not. */ - .filter( - ({ id }) => - actionTypes ?? - (!DEFAULT_HIDDEN_ACTION_TYPES.includes(id) && - !DEFAULT_HIDDEN_ONLY_ON_ALERTS_ACTION_TYPES.includes(id)) - ) + .filter(({ id }) => actionTypes ?? !DEFAULT_HIDDEN_ACTION_TYPES.includes(id)) .filter((item) => actionTypesIndex[item.id]) .filter((item) => !!item.actionParamsFields) .sort((a, b) => diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx index 1a3a186d891cc..16466fc9a210d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx @@ -33,6 +33,7 @@ import { IErrorObject, ConnectorAddFlyoutProps, ActionTypeModel, + ActionConnectorFieldsCallbacks, } from '../../../types'; import { hasSaveActionsCapability } from '../../lib/capabilities'; import { createActionConnector } from '../../lib/action_connector_api'; @@ -121,6 +122,7 @@ const ConnectorAddFlyout: React.FunctionComponent<ConnectorAddFlyoutProps> = ({ }; const [isSaving, setIsSaving] = useState<boolean>(false); + const [callbacks, setCallbacks] = useState<ActionConnectorFieldsCallbacks>(null); const closeFlyout = useCallback(() => { onClose(); @@ -155,6 +157,8 @@ const ConnectorAddFlyout: React.FunctionComponent<ConnectorAddFlyoutProps> = ({ errors={errors.connectorErrors} actionTypeRegistry={actionTypeRegistry} consumer={consumer} + setCallbacks={setCallbacks} + isEdit={false} /> ); @@ -199,10 +203,21 @@ const ConnectorAddFlyout: React.FunctionComponent<ConnectorAddFlyoutProps> = ({ ); return; } + setIsSaving(true); + // Do not allow to save the connector if there is an error + try { + await callbacks?.beforeActionConnectorSave?.(); + } catch (e) { + setIsSaving(false); + return; + } + const savedAction = await onActionConnectorSave(); + setIsSaving(false); if (savedAction) { + await callbacks?.afterActionConnectorSave?.(savedAction); closeFlyout(); if (reloadConnectors) { await reloadConnectors(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 1e9669d1995dd..7fd6931c936f5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -33,6 +33,7 @@ import { ActionTypeRegistryContract, UserConfiguredActionConnector, IErrorObject, + ActionConnectorFieldsCallbacks, } from '../../../types'; import { useKibana } from '../../../common/lib/kibana'; import { getConnectorWithInvalidatedFields } from '../../lib/value_validators'; @@ -97,6 +98,7 @@ const ConnectorAddModal = ({ secretsErrors: {}, }); + const [callbacks, setCallbacks] = useState<ActionConnectorFieldsCallbacks>(null); const actionTypeModel = actionTypeRegistry.get(actionType.id); useEffect(() => { @@ -189,6 +191,8 @@ const ConnectorAddModal = ({ errors={errors.connectorErrors} actionTypeRegistry={actionTypeRegistry} consumer={consumer} + setCallbacks={setCallbacks} + isEdit={false} /> {isLoading ? ( <> @@ -230,9 +234,19 @@ const ConnectorAddModal = ({ return; } setIsSaving(true); + // Do not allow to save the connector if there is an error + try { + await callbacks?.beforeActionConnectorSave?.(); + } catch (e) { + setIsSaving(false); + return; + } + const savedAction = await onActionConnectorSave(); + setIsSaving(false); if (savedAction) { + await callbacks?.afterActionConnectorSave?.(savedAction); if (postSaveEventHandler) { postSaveEventHandler(savedAction); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx index 25c8103f0c8dc..206ae0bf5018b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx @@ -35,6 +35,7 @@ import { IErrorObject, EditConectorTabs, UserConfiguredActionConnector, + ActionConnectorFieldsCallbacks, } from '../../../types'; import { ConnectorReducer, createConnectorReducer } from './connector_reducer'; import { updateActionConnector, executeAction } from '../../lib/action_connector_api'; @@ -138,6 +139,8 @@ const ConnectorEditFlyout = ({ [testExecutionResult] ); + const [callbacks, setCallbacks] = useState<ActionConnectorFieldsCallbacks>(null); + const closeFlyout = useCallback(() => { setConnector(getConnectorWithoutSecrets()); setHasChanges(false); @@ -236,23 +239,38 @@ const ConnectorEditFlyout = ({ }); }; + const setConnectorWithErrors = () => + setConnector( + getConnectorWithInvalidatedFields( + connector, + errors.configErrors, + errors.secretsErrors, + errors.connectorBaseErrors + ) + ); + const onSaveClicked = async (closeAfterSave: boolean = true) => { if (hasErrors) { - setConnector( - getConnectorWithInvalidatedFields( - connector, - errors.configErrors, - errors.secretsErrors, - errors.connectorBaseErrors - ) - ); + setConnectorWithErrors(); return; } + setIsSaving(true); + + // Do not allow to save the connector if there is an error + try { + await callbacks?.beforeActionConnectorSave?.(); + } catch (e) { + setIsSaving(false); + return; + } + const savedAction = await onActionConnectorSave(); setIsSaving(false); + if (savedAction) { setHasChanges(false); + await callbacks?.afterActionConnectorSave?.(savedAction); if (closeAfterSave) { closeFlyout(); } @@ -313,6 +331,8 @@ const ConnectorEditFlyout = ({ }} actionTypeRegistry={actionTypeRegistry} consumer={consumer} + setCallbacks={setCallbacks} + isEdit={true} /> {isLoading ? ( <> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index c237bbda48658..04f2334f8e8fa 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -38,6 +38,7 @@ import { ActionConnectorTableItem, ActionTypeIndex, EditConectorTabs, + UserConfiguredActionConnector, } from '../../../../types'; import { EmptyConnectorsPrompt } from '../../../components/prompts/empty_connectors_prompt'; import { useKibana } from '../../../../common/lib/kibana'; @@ -45,6 +46,11 @@ import { DEFAULT_HIDDEN_ACTION_TYPES } from '../../../../'; import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner'; import ConnectorEditFlyout from '../../action_connector_form/connector_edit_flyout'; import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout'; +import { + ENABLE_NEW_SN_ITSM_CONNECTOR, + ENABLE_NEW_SN_SIR_CONNECTOR, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../actions/server/constants/connectors'; const ActionsConnectorsList: React.FunctionComponent = () => { const { @@ -167,6 +173,14 @@ const ActionsConnectorsList: React.FunctionComponent = () => { const checkEnabledResult = checkActionTypeEnabled( actionTypesIndex && actionTypesIndex[item.actionTypeId] ); + const itemConfig = ( + item as UserConfiguredActionConnector<Record<string, unknown>, Record<string, unknown>> + ).config; + const showLegacyTooltip = + itemConfig?.isLegacy && + // TODO: Remove when applications are certified + ((ENABLE_NEW_SN_ITSM_CONNECTOR && item.actionTypeId === '.servicenow') || + (ENABLE_NEW_SN_SIR_CONNECTOR && item.actionTypeId === '.servicenow-sir')); const link = ( <> @@ -190,6 +204,23 @@ const ActionsConnectorsList: React.FunctionComponent = () => { position="right" /> ) : null} + {showLegacyTooltip && ( + <EuiIconTip + aria-label="Warning" + size="m" + type="alert" + color="warning" + title={i18n.translate( + 'xpack.triggersActionsUI.sections.actionsConnectorsList.connectorsListTable.columns.actions.legacyConnectorTitle', + { defaultMessage: 'Deprecated connector' } + )} + content={i18n.translate( + 'xpack.triggersActionsUI.sections.actionsConnectorsList.connectorsListTable.columns.actions.isLegacyDescription', + { defaultMessage: 'Please update your connector' } + )} + position="right" + /> + )} </> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.test.tsx index c07138990f88d..847c6c65464b2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.test.tsx @@ -19,20 +19,6 @@ import { spacesPluginMock } from '../../../../../../spaces/public/mocks'; import { useKibana } from '../../../../common/lib/kibana'; jest.mock('../../../../common/lib/kibana'); -class NotFoundError extends Error { - public readonly body: { - statusCode: number; - name: string; - } = { - statusCode: 404, - name: 'Not found', - }; - - constructor(message: string | undefined) { - super(message); - } -} - describe('alert_details_route', () => { beforeEach(() => { jest.clearAllMocks(); @@ -58,11 +44,8 @@ describe('alert_details_route', () => { it('redirects to another page if fetched rule is an aliasMatch', async () => { await setup(); const rule = mockRule(); - const { loadAlert, resolveRule } = mockApis(); + const { resolveRule } = mockApis(); - loadAlert.mockImplementationOnce(async () => { - throw new NotFoundError('OMG'); - }); resolveRule.mockImplementationOnce(async () => ({ ...rule, id: 'new_id', @@ -70,17 +53,13 @@ describe('alert_details_route', () => { alias_target_id: rule.id, })); const wrapper = mountWithIntl( - <AlertDetailsRoute - {...mockRouterProps(rule)} - {...{ ...mockApis(), loadAlert, resolveRule }} - /> + <AlertDetailsRoute {...mockRouterProps(rule)} {...{ ...mockApis(), resolveRule }} /> ); await act(async () => { await nextTick(); wrapper.update(); }); - expect(loadAlert).toHaveBeenCalledWith(rule.id); expect(resolveRule).toHaveBeenCalledWith(rule.id); expect((spacesMock as any).ui.redirectLegacyUrl).toHaveBeenCalledWith( `insightsAndAlerting/triggersActions/rule/new_id`, @@ -96,11 +75,8 @@ describe('alert_details_route', () => { name: 'type name', authorizedConsumers: ['consumer'], }; - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); - loadAlert.mockImplementationOnce(async () => { - throw new NotFoundError('OMG'); - }); loadAlertTypes.mockImplementationOnce(async () => [ruleType]); loadActionTypes.mockImplementation(async () => []); resolveRule.mockImplementationOnce(async () => ({ @@ -112,7 +88,7 @@ describe('alert_details_route', () => { const wrapper = mountWithIntl( <AlertDetailsRoute {...mockRouterProps(rule)} - {...{ ...mockApis(), loadAlert, loadAlertTypes, loadActionTypes, resolveRule }} + {...{ ...mockApis(), loadAlertTypes, loadActionTypes, resolveRule }} /> ); await act(async () => { @@ -120,7 +96,6 @@ describe('alert_details_route', () => { wrapper.update(); }); - expect(loadAlert).toHaveBeenCalledWith(rule.id); expect(resolveRule).toHaveBeenCalledWith(rule.id); expect((spacesMock as any).ui.components.getLegacyUrlConflict).toHaveBeenCalledWith({ currentObjectId: 'new_id', @@ -138,10 +113,10 @@ describe('getRuleData useEffect handler', () => { it('fetches rule', async () => { const rule = mockRule(); - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementationOnce(async () => rule); + resolveRule.mockImplementationOnce(async () => rule); const toastNotifications = { addDanger: jest.fn(), @@ -149,7 +124,6 @@ describe('getRuleData useEffect handler', () => { await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -159,8 +133,7 @@ describe('getRuleData useEffect handler', () => { toastNotifications ); - expect(loadAlert).toHaveBeenCalledWith(rule.id); - expect(resolveRule).not.toHaveBeenCalled(); + expect(resolveRule).toHaveBeenCalledWith(rule.id); expect(setAlert).toHaveBeenCalledWith(rule); }); @@ -184,10 +157,10 @@ describe('getRuleData useEffect handler', () => { id: rule.alertTypeId, name: 'type name', }; - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementation(async () => rule); + resolveRule.mockImplementation(async () => rule); loadAlertTypes.mockImplementation(async () => [ruleType]); loadActionTypes.mockImplementation(async () => [connectorType]); @@ -197,7 +170,6 @@ describe('getRuleData useEffect handler', () => { await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -209,58 +181,13 @@ describe('getRuleData useEffect handler', () => { expect(loadAlertTypes).toHaveBeenCalledTimes(1); expect(loadActionTypes).toHaveBeenCalledTimes(1); - expect(resolveRule).not.toHaveBeenCalled(); + expect(resolveRule).toHaveBeenCalled(); expect(setAlert).toHaveBeenCalledWith(rule); expect(setAlertType).toHaveBeenCalledWith(ruleType); expect(setActionTypes).toHaveBeenCalledWith([connectorType]); }); - it('fetches rule using resolve if initial GET results in a 404 error', async () => { - const connectorType = { - id: '.server-log', - name: 'Server log', - enabled: true, - }; - const rule = mockRule({ - actions: [ - { - group: '', - id: uuid.v4(), - actionTypeId: connectorType.id, - params: {}, - }, - ], - }); - - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); - const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - - loadAlert.mockImplementationOnce(async () => { - throw new NotFoundError('OMG'); - }); - resolveRule.mockImplementationOnce(async () => rule); - - const toastNotifications = { - addDanger: jest.fn(), - } as unknown as ToastsApi; - await getRuleData( - rule.id, - loadAlert, - loadAlertTypes, - resolveRule, - loadActionTypes, - setAlert, - setAlertType, - setActionTypes, - toastNotifications - ); - - expect(loadAlert).toHaveBeenCalledWith(rule.id); - expect(resolveRule).toHaveBeenCalledWith(rule.id); - expect(setAlert).toHaveBeenCalledWith(rule); - }); - it('displays an error if fetching the rule results in a non-404 error', async () => { const connectorType = { id: '.server-log', @@ -278,10 +205,10 @@ describe('getRuleData useEffect handler', () => { ], }); - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementation(async () => { + resolveRule.mockImplementation(async () => { throw new Error('OMG'); }); @@ -290,7 +217,6 @@ describe('getRuleData useEffect handler', () => { } as unknown as ToastsApi; await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -322,10 +248,10 @@ describe('getRuleData useEffect handler', () => { ], }); - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementation(async () => rule); + resolveRule.mockImplementation(async () => rule); loadAlertTypes.mockImplementation(async () => { throw new Error('OMG no rule type'); @@ -337,7 +263,6 @@ describe('getRuleData useEffect handler', () => { } as unknown as ToastsApi; await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -373,10 +298,10 @@ describe('getRuleData useEffect handler', () => { name: 'type name', }; - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementation(async () => rule); + resolveRule.mockImplementation(async () => rule); loadAlertTypes.mockImplementation(async () => [ruleType]); loadActionTypes.mockImplementation(async () => { @@ -388,7 +313,6 @@ describe('getRuleData useEffect handler', () => { } as unknown as ToastsApi; await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -425,10 +349,10 @@ describe('getRuleData useEffect handler', () => { name: 'type name', }; - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementation(async () => rule); + resolveRule.mockImplementation(async () => rule); loadAlertTypes.mockImplementation(async () => [ruleType]); loadActionTypes.mockImplementation(async () => [connectorType]); @@ -437,7 +361,6 @@ describe('getRuleData useEffect handler', () => { } as unknown as ToastsApi; await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -485,10 +408,10 @@ describe('getRuleData useEffect handler', () => { name: 'type name', }; - const { loadAlert, loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); + const { loadAlertTypes, loadActionTypes, resolveRule } = mockApis(); const { setAlert, setAlertType, setActionTypes } = mockStateSetter(); - loadAlert.mockImplementation(async () => rule); + resolveRule.mockImplementation(async () => rule); loadAlertTypes.mockImplementation(async () => [ruleType]); loadActionTypes.mockImplementation(async () => [availableConnectorType]); @@ -497,7 +420,6 @@ describe('getRuleData useEffect handler', () => { } as unknown as ToastsApi; await getRuleData( rule.id, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.tsx index 123d60bb9fea3..b530df986c277 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details_route.tsx @@ -10,7 +10,7 @@ import React, { useState, useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { ToastsApi } from 'kibana/public'; import { EuiSpacer } from '@elastic/eui'; -import { Alert, AlertType, ActionType, ResolvedRule } from '../../../../types'; +import { AlertType, ActionType, ResolvedRule } from '../../../../types'; import { AlertDetailsWithApi as AlertDetails } from './alert_details'; import { throwIfAbsent, throwIfIsntContained } from '../../../lib/value_validators'; import { @@ -28,13 +28,12 @@ type AlertDetailsRouteProps = RouteComponentProps<{ ruleId: string; }> & Pick<ActionApis, 'loadActionTypes'> & - Pick<AlertApis, 'loadAlert' | 'loadAlertTypes' | 'resolveRule'>; + Pick<AlertApis, 'loadAlertTypes' | 'resolveRule'>; export const AlertDetailsRoute: React.FunctionComponent<AlertDetailsRouteProps> = ({ match: { params: { ruleId }, }, - loadAlert, loadAlertTypes, loadActionTypes, resolveRule, @@ -47,14 +46,13 @@ export const AlertDetailsRoute: React.FunctionComponent<AlertDetailsRouteProps> const { basePath } = http; - const [alert, setAlert] = useState<Alert | ResolvedRule | null>(null); + const [alert, setAlert] = useState<ResolvedRule | null>(null); const [alertType, setAlertType] = useState<AlertType | null>(null); const [actionTypes, setActionTypes] = useState<ActionType[] | null>(null); const [refreshToken, requestRefresh] = React.useState<number>(); useEffect(() => { getRuleData( ruleId, - loadAlert, loadAlertTypes, resolveRule, loadActionTypes, @@ -63,7 +61,7 @@ export const AlertDetailsRoute: React.FunctionComponent<AlertDetailsRouteProps> setActionTypes, toasts ); - }, [ruleId, http, loadActionTypes, loadAlert, loadAlertTypes, resolveRule, toasts, refreshToken]); + }, [ruleId, http, loadActionTypes, loadAlertTypes, resolveRule, toasts, refreshToken]); useEffect(() => { if (alert) { @@ -128,26 +126,16 @@ export const AlertDetailsRoute: React.FunctionComponent<AlertDetailsRouteProps> export async function getRuleData( ruleId: string, - loadAlert: AlertApis['loadAlert'], loadAlertTypes: AlertApis['loadAlertTypes'], resolveRule: AlertApis['resolveRule'], loadActionTypes: ActionApis['loadActionTypes'], - setAlert: React.Dispatch<React.SetStateAction<Alert | ResolvedRule | null>>, + setAlert: React.Dispatch<React.SetStateAction<ResolvedRule | null>>, setAlertType: React.Dispatch<React.SetStateAction<AlertType | null>>, setActionTypes: React.Dispatch<React.SetStateAction<ActionType[] | null>>, toasts: Pick<ToastsApi, 'addDanger'> ) { try { - let loadedRule: Alert | ResolvedRule; - try { - loadedRule = await loadAlert(ruleId); - } catch (err) { - // Try resolving this rule id if the error is a 404, otherwise re-throw - if (err?.body?.statusCode !== 404) { - throw err; - } - loadedRule = await resolveRule(ruleId); - } + const loadedRule: ResolvedRule = await resolveRule(ruleId); setAlert(loadedRule); const [loadedAlertType, loadedActionTypes] = await Promise.all<AlertType, ActionType[]>([ diff --git a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts index c2523dd59821d..9e490945e2261 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts @@ -12,5 +12,3 @@ export { builtInGroupByTypes } from './group_by_types'; export const VIEW_LICENSE_OPTIONS_LINK = 'https://www.elastic.co/subscriptions'; // TODO: Remove when cases connector is available across Kibana. Issue: https://github.com/elastic/kibana/issues/82502. export const DEFAULT_HIDDEN_ACTION_TYPES = ['.case']; -// Action types included in this array will be hidden only from the alert's action type node list -export const DEFAULT_HIDDEN_ONLY_ON_ALERTS_ACTION_TYPES = ['.servicenow-sir']; diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index a78d1d52de0bd..8085f9245f4e9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -73,6 +73,14 @@ export type ActionTypeRegistryContract< > = PublicMethodsOf<TypeRegistry<ActionTypeModel<ActionConnector, ActionParams>>>; export type RuleTypeRegistryContract = PublicMethodsOf<TypeRegistry<AlertTypeModel>>; +export type ActionConnectorFieldsCallbacks = { + beforeActionConnectorSave?: () => Promise<void>; + afterActionConnectorSave?: (connector: ActionConnector) => Promise<void>; +} | null; +export type ActionConnectorFieldsSetCallbacks = React.Dispatch< + React.SetStateAction<ActionConnectorFieldsCallbacks> +>; + export interface ActionConnectorFieldsProps<TActionConnector> { action: TActionConnector; editActionConfig: (property: string, value: unknown) => void; @@ -80,6 +88,8 @@ export interface ActionConnectorFieldsProps<TActionConnector> { errors: IErrorObject; readOnly: boolean; consumer?: string; + setCallbacks: ActionConnectorFieldsSetCallbacks; + isEdit: boolean; } export enum AlertFlyoutCloseReason { diff --git a/x-pack/plugins/uptime/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap index 95c5a9dbc418b..45b162e13fb9b 100644 --- a/x-pack/plugins/uptime/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap @@ -347,10 +347,18 @@ exports[`DonutChart component passes correct props without errors for valid prop }, "barSeriesStyle": Object { "displayValue": Object { - "fill": "rgba(106, 113, 125, 1)", + "alignment": Object { + "horizontal": "center", + "vertical": "middle", + }, + "fill": Object { + "textBorder": 0, + "textContrast": true, + "textInvertible": true, + }, "fontFamily": "'Inter', 'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", - "fontSize": 8, + "fontSize": 10, }, }, "chartMargins": Object { diff --git a/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.test.tsx b/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.test.tsx index aa1f7ca07e3d8..fabf6da49cf47 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.test.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.test.tsx @@ -9,10 +9,12 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import { render } from '../../../lib/helper/rtl_helpers'; import { BrowserAdvancedFields } from './advanced_fields'; -import { ConfigKeys, IBrowserAdvancedFields } from '../types'; +import { ConfigKeys, IBrowserAdvancedFields, IBrowserSimpleFields } from '../types'; import { BrowserAdvancedFieldsContextProvider, + BrowserSimpleFieldsContextProvider, defaultBrowserAdvancedFields as defaultConfig, + defaultBrowserSimpleFields, } from '../contexts'; jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ @@ -20,11 +22,19 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ })); describe('<BrowserAdvancedFields />', () => { - const WrappedComponent = ({ defaultValues }: { defaultValues?: IBrowserAdvancedFields }) => { + const WrappedComponent = ({ + defaultValues = defaultConfig, + defaultSimpleFields = defaultBrowserSimpleFields, + }: { + defaultValues?: IBrowserAdvancedFields; + defaultSimpleFields?: IBrowserSimpleFields; + }) => { return ( - <BrowserAdvancedFieldsContextProvider defaultValues={defaultValues}> - <BrowserAdvancedFields /> - </BrowserAdvancedFieldsContextProvider> + <BrowserSimpleFieldsContextProvider defaultValues={defaultSimpleFields}> + <BrowserAdvancedFieldsContextProvider defaultValues={defaultValues}> + <BrowserAdvancedFields /> + </BrowserAdvancedFieldsContextProvider> + </BrowserSimpleFieldsContextProvider> ); }; @@ -46,4 +56,29 @@ describe('<BrowserAdvancedFields />', () => { expect(screenshots.value).toEqual('off'); }); + + it('only displayed filter options when zip url is truthy', () => { + const { queryByText, getByText, rerender } = render(<WrappedComponent />); + + expect( + queryByText( + /Use these options to apply the selected monitor settings to a subset of the tests in your suite./ + ) + ).not.toBeInTheDocument(); + + rerender( + <WrappedComponent + defaultSimpleFields={{ + ...defaultBrowserSimpleFields, + [ConfigKeys.SOURCE_ZIP_URL]: 'https://elastic.zip', + }} + /> + ); + + expect( + getByText( + /Use these options to apply the selected monitor settings to a subset of the tests in your suite./ + ) + ).toBeInTheDocument(); + }); }); diff --git a/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.tsx b/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.tsx index 28e2e39c79554..61af9f8ec6143 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/browser/advanced_fields.tsx @@ -10,13 +10,15 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiAccordion, EuiSelect, + EuiFieldText, + EuiCheckbox, EuiFormRow, EuiDescribedFormGroup, EuiSpacer, } from '@elastic/eui'; import { ComboBox } from '../combo_box'; -import { useBrowserAdvancedFieldsContext } from '../contexts'; +import { useBrowserAdvancedFieldsContext, useBrowserSimpleFieldsContext } from '../contexts'; import { ConfigKeys, ScreenshotOption } from '../types'; @@ -24,6 +26,7 @@ import { OptionalLabel } from '../optional_label'; export const BrowserAdvancedFields = () => { const { fields, setFields } = useBrowserAdvancedFieldsContext(); + const { fields: simpleFields } = useBrowserSimpleFieldsContext(); const handleInputChange = useCallback( ({ value, configKey }: { value: unknown; configKey: ConfigKeys }) => { @@ -39,6 +42,75 @@ export const BrowserAdvancedFields = () => { data-test-subj="syntheticsBrowserAdvancedFieldsAccordion" > <EuiSpacer size="m" /> + {simpleFields[ConfigKeys.SOURCE_ZIP_URL] && ( + <EuiDescribedFormGroup + title={ + <h4> + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title" + defaultMessage="Selective tests" + /> + </h4> + } + description={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description" + defaultMessage="Use these options to apply the selected monitor settings to a subset of the tests in your suite. Only the configured subset will be run by this monitor." + /> + } + > + <EuiSpacer size="s" /> + <EuiFormRow + label={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label" + defaultMessage="Filter match" + /> + } + labelAppend={<OptionalLabel />} + helpText={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText" + defaultMessage="Run only journeys with a name that matches the provided glob with this monitor." + /> + } + > + <EuiFieldText + value={fields[ConfigKeys.JOURNEY_FILTERS_MATCH]} + onChange={(event) => + handleInputChange({ + value: event.target.value, + configKey: ConfigKeys.JOURNEY_FILTERS_MATCH, + }) + } + data-test-subj="syntheticsBrowserJourneyFiltersMatch" + /> + </EuiFormRow> + <EuiFormRow + label={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label" + defaultMessage="Filter tags" + /> + } + labelAppend={<OptionalLabel />} + helpText={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText" + defaultMessage="Run only journeys with the given tags with this monitor." + /> + } + > + <ComboBox + selectedOptions={fields[ConfigKeys.JOURNEY_FILTERS_TAGS]} + onChange={(value) => + handleInputChange({ value, configKey: ConfigKeys.JOURNEY_FILTERS_TAGS }) + } + data-test-subj="syntheticsBrowserJourneyFiltersTags" + /> + </EuiFormRow> + </EuiDescribedFormGroup> + )} <EuiDescribedFormGroup title={ <h4> @@ -56,6 +128,34 @@ export const BrowserAdvancedFields = () => { } > <EuiSpacer size="s" /> + <EuiFormRow + helpText={ + <> + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText" + defaultMessage="Set this option to true to disable TLS/SSL validation in the synthetics browser. This is useful for testing sites that use self-signed certs." + /> + </> + } + data-test-subj="syntheticsBrowserIgnoreHttpsErrors" + > + <EuiCheckbox + id="syntheticsBrowserIgnoreHttpsErrorsCheckbox" + checked={fields[ConfigKeys.IGNORE_HTTPS_ERRORS]} + label={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label" + defaultMessage="Ignore HTTPS errors" + /> + } + onChange={(event) => + handleInputChange({ + value: event.target.checked, + configKey: ConfigKeys.IGNORE_HTTPS_ERRORS, + }) + } + /> + </EuiFormRow> <EuiFormRow label={ <FormattedMessage diff --git a/x-pack/plugins/uptime/public/components/fleet_package/browser/formatters.ts b/x-pack/plugins/uptime/public/components/fleet_package/browser/formatters.ts index 183ffa53cc339..5bc44775ee2f5 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/browser/formatters.ts +++ b/x-pack/plugins/uptime/public/components/fleet_package/browser/formatters.ts @@ -25,5 +25,10 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKeys.SCREENSHOTS]: null, [ConfigKeys.SYNTHETICS_ARGS]: (fields) => arrayToJsonFormatter(fields[ConfigKeys.SYNTHETICS_ARGS]), + [ConfigKeys.JOURNEY_FILTERS_MATCH]: (fields) => + stringToJsonFormatter(fields[ConfigKeys.JOURNEY_FILTERS_MATCH]), + [ConfigKeys.JOURNEY_FILTERS_TAGS]: (fields) => + arrayToJsonFormatter(fields[ConfigKeys.JOURNEY_FILTERS_TAGS]), + [ConfigKeys.IGNORE_HTTPS_ERRORS]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/uptime/public/components/fleet_package/browser/normalizers.ts b/x-pack/plugins/uptime/public/components/fleet_package/browser/normalizers.ts index 53bbf611d490c..0107fb3884f41 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/browser/normalizers.ts +++ b/x-pack/plugins/uptime/public/components/fleet_package/browser/normalizers.ts @@ -39,5 +39,12 @@ export const browserNormalizers: BrowserNormalizerMap = { [ConfigKeys.PARAMS]: getBrowserNormalizer(ConfigKeys.PARAMS), [ConfigKeys.SCREENSHOTS]: getBrowserNormalizer(ConfigKeys.SCREENSHOTS), [ConfigKeys.SYNTHETICS_ARGS]: getBrowserJsonToJavascriptNormalizer(ConfigKeys.SYNTHETICS_ARGS), + [ConfigKeys.JOURNEY_FILTERS_MATCH]: getBrowserJsonToJavascriptNormalizer( + ConfigKeys.JOURNEY_FILTERS_MATCH + ), + [ConfigKeys.JOURNEY_FILTERS_TAGS]: getBrowserJsonToJavascriptNormalizer( + ConfigKeys.JOURNEY_FILTERS_TAGS + ), + [ConfigKeys.IGNORE_HTTPS_ERRORS]: getBrowserNormalizer(ConfigKeys.IGNORE_HTTPS_ERRORS), ...commonNormalizers, }; diff --git a/x-pack/plugins/uptime/public/components/fleet_package/browser/simple_fields.tsx b/x-pack/plugins/uptime/public/components/fleet_package/browser/simple_fields.tsx index 0e2f10b96fe6d..7c7a6b199adcb 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/browser/simple_fields.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/browser/simple_fields.tsx @@ -7,13 +7,12 @@ import React, { memo, useMemo, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; +import { EuiFormRow } from '@elastic/eui'; import { ConfigKeys, Validation } from '../types'; import { useBrowserSimpleFieldsContext } from '../contexts'; -import { ComboBox } from '../combo_box'; -import { OptionalLabel } from '../optional_label'; import { ScheduleField } from '../schedule_field'; import { SourceField } from './source_field'; +import { CommonFields } from '../common/common_fields'; interface Props { validate: Validation; @@ -91,93 +90,7 @@ export const BrowserSimpleFields = memo<Props>(({ validate }) => { )} /> </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label" - defaultMessage="APM service name" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText" - defaultMessage="APM service name for this monitor. Corresponds to the service.name ECS field. Set this when monitoring an app that is also using APM to enable integrations between Uptime and APM data in Kibana." - /> - } - > - <EuiFieldText - value={fields[ConfigKeys.APM_SERVICE_NAME]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.APM_SERVICE_NAME, - }) - } - data-test-subj="syntheticsAPMServiceName" - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label" - defaultMessage="Timeout in seconds" - /> - } - isInvalid={!!validate[ConfigKeys.TIMEOUT]?.(fields)} - error={ - parseInt(fields[ConfigKeys.TIMEOUT], 10) < 0 ? ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError" - defaultMessage="Timeout must be greater than or equal to 0" - /> - ) : ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError" - defaultMessage="Timeout must be less than the monitor interval" - /> - ) - } - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText" - defaultMessage="The total time allowed for testing the connection and exchanging data." - /> - } - > - <EuiFieldNumber - min={0} - value={fields[ConfigKeys.TIMEOUT]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.TIMEOUT, - }) - } - step={'any'} - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label" - defaultMessage="Tags" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText" - defaultMessage="A list of tags that will be sent with the monitor event. Press enter to add a new tag. Displayed in Uptime and enables searching by tag." - /> - } - > - <ComboBox - selectedOptions={fields[ConfigKeys.TAGS]} - onChange={(value) => handleInputChange({ value, configKey: ConfigKeys.TAGS })} - data-test-subj="syntheticsTags" - /> - </EuiFormRow> + <CommonFields fields={fields} onChange={handleInputChange} validate={validate} /> </> ); }); diff --git a/x-pack/plugins/uptime/public/components/fleet_package/common/common_fields.tsx b/x-pack/plugins/uptime/public/components/fleet_package/common/common_fields.tsx new file mode 100644 index 0000000000000..57d5094958ca3 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/fleet_package/common/common_fields.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 { FormattedMessage } from '@kbn/i18n/react'; +import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; +import { ConfigKeys, Validation, ICommonFields } from '../types'; +import { ComboBox } from '../combo_box'; +import { OptionalLabel } from '../optional_label'; + +interface Props { + validate: Validation; + fields: ICommonFields; + onChange: ({ value, configKey }: { value: string | string[]; configKey: ConfigKeys }) => void; +} + +export function CommonFields({ fields, onChange, validate }: Props) { + return ( + <> + <EuiFormRow + label={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label" + defaultMessage="APM service name" + /> + } + labelAppend={<OptionalLabel />} + helpText={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText" + defaultMessage="APM service name for this monitor. Corresponds to the service.name ECS field. Set this when monitoring an app that is also using APM to enable integrations between Uptime and APM data in Kibana." + /> + } + > + <EuiFieldText + value={fields[ConfigKeys.APM_SERVICE_NAME]} + onChange={(event) => + onChange({ + value: event.target.value, + configKey: ConfigKeys.APM_SERVICE_NAME, + }) + } + data-test-subj="syntheticsAPMServiceName" + /> + </EuiFormRow> + <EuiFormRow + label={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label" + defaultMessage="Timeout in seconds" + /> + } + isInvalid={!!validate[ConfigKeys.TIMEOUT]?.(fields)} + error={ + parseInt(fields[ConfigKeys.TIMEOUT], 10) < 0 ? ( + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError" + defaultMessage="Timeout must be greater than or equal to 0" + /> + ) : ( + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError" + defaultMessage="Timeout must be less than the monitor interval" + /> + ) + } + helpText={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText" + defaultMessage="The total time allowed for testing the connection and exchanging data." + /> + } + > + <EuiFieldNumber + min={0} + value={fields[ConfigKeys.TIMEOUT]} + onChange={(event) => + onChange({ + value: event.target.value, + configKey: ConfigKeys.TIMEOUT, + }) + } + step={'any'} + /> + </EuiFormRow> + <EuiFormRow + label={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label" + defaultMessage="Tags" + /> + } + labelAppend={<OptionalLabel />} + helpText={ + <FormattedMessage + id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText" + defaultMessage="A list of tags that will be sent with the monitor event. Press enter to add a new tag. Displayed in Uptime and enables searching by tag." + /> + } + > + <ComboBox + selectedOptions={fields[ConfigKeys.TAGS]} + onChange={(value) => onChange({ value, configKey: ConfigKeys.TAGS })} + data-test-subj="syntheticsTags" + /> + </EuiFormRow> + </> + ); +} diff --git a/x-pack/plugins/uptime/public/components/fleet_package/contexts/browser_context_advanced.tsx b/x-pack/plugins/uptime/public/components/fleet_package/contexts/browser_context_advanced.tsx index 3f3bb8f14c269..bc766462f18ae 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/contexts/browser_context_advanced.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/contexts/browser_context_advanced.tsx @@ -22,6 +22,9 @@ interface IBrowserAdvancedFieldsContextProvider { export const initialValues: IBrowserAdvancedFields = { [ConfigKeys.SCREENSHOTS]: ScreenshotOption.ON, [ConfigKeys.SYNTHETICS_ARGS]: [], + [ConfigKeys.JOURNEY_FILTERS_MATCH]: '', + [ConfigKeys.JOURNEY_FILTERS_TAGS]: [], + [ConfigKeys.IGNORE_HTTPS_ERRORS]: false, }; const defaultContext: IBrowserAdvancedFieldsContext = { diff --git a/x-pack/plugins/uptime/public/components/fleet_package/contexts/advanced_fields_http_context.tsx b/x-pack/plugins/uptime/public/components/fleet_package/contexts/http_context_advanced.tsx similarity index 100% rename from x-pack/plugins/uptime/public/components/fleet_package/contexts/advanced_fields_http_context.tsx rename to x-pack/plugins/uptime/public/components/fleet_package/contexts/http_context_advanced.tsx diff --git a/x-pack/plugins/uptime/public/components/fleet_package/contexts/index.ts b/x-pack/plugins/uptime/public/components/fleet_package/contexts/index.ts index e955d2d7d4d50..4d76a6d8f8d67 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/contexts/index.ts +++ b/x-pack/plugins/uptime/public/components/fleet_package/contexts/index.ts @@ -21,7 +21,7 @@ export { HTTPAdvancedFieldsContextProvider, initialValues as defaultHTTPAdvancedFields, useHTTPAdvancedFieldsContext, -} from './advanced_fields_http_context'; +} from './http_context_advanced'; export { TCPSimpleFieldsContext, TCPSimpleFieldsContextProvider, @@ -39,7 +39,7 @@ export { TCPAdvancedFieldsContextProvider, initialValues as defaultTCPAdvancedFields, useTCPAdvancedFieldsContext, -} from './advanced_fields_tcp_context'; +} from './tcp_context_advanced'; export { BrowserSimpleFieldsContext, BrowserSimpleFieldsContextProvider, diff --git a/x-pack/plugins/uptime/public/components/fleet_package/contexts/advanced_fields_tcp_context.tsx b/x-pack/plugins/uptime/public/components/fleet_package/contexts/tcp_context_advanced.tsx similarity index 100% rename from x-pack/plugins/uptime/public/components/fleet_package/contexts/advanced_fields_tcp_context.tsx rename to x-pack/plugins/uptime/public/components/fleet_package/contexts/tcp_context_advanced.tsx diff --git a/x-pack/plugins/uptime/public/components/fleet_package/http/simple_fields.tsx b/x-pack/plugins/uptime/public/components/fleet_package/http/simple_fields.tsx index c4de1d53fe998..90f94324fe657 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/http/simple_fields.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/http/simple_fields.tsx @@ -10,9 +10,9 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; import { ConfigKeys, Validation } from '../types'; import { useHTTPSimpleFieldsContext } from '../contexts'; -import { ComboBox } from '../combo_box'; import { OptionalLabel } from '../optional_label'; import { ScheduleField } from '../schedule_field'; +import { CommonFields } from '../common/common_fields'; interface Props { validate: Validation; @@ -50,7 +50,7 @@ export const HTTPSimpleFields = memo<Props>(({ validate }) => { /> </EuiFormRow> <EuiFormRow - id="syntheticsFleetScheduleField--number syntheticsFleetScheduleField--unit" + id="syntheticsFleetScheduleField" label={ <FormattedMessage id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval" @@ -76,32 +76,6 @@ export const HTTPSimpleFields = memo<Props>(({ validate }) => { unit={fields[ConfigKeys.SCHEDULE].unit} /> </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label" - defaultMessage="APM service name" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText" - defaultMessage="APM service name for this monitor. Corresponds to the service.name ECS field. Set this when monitoring an app that is also using APM to enable integrations between Uptime and APM data in Kibana." - /> - } - > - <EuiFieldText - value={fields[ConfigKeys.APM_SERVICE_NAME]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.APM_SERVICE_NAME, - }) - } - data-test-subj="syntheticsAPMServiceName" - /> - </EuiFormRow> <EuiFormRow label={ <FormattedMessage @@ -135,67 +109,7 @@ export const HTTPSimpleFields = memo<Props>(({ validate }) => { } /> </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label" - defaultMessage="Timeout in seconds" - /> - } - isInvalid={!!validate[ConfigKeys.TIMEOUT]?.(fields)} - error={ - parseInt(fields[ConfigKeys.TIMEOUT], 10) < 0 ? ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError" - defaultMessage="Timeout must be greater than or equal to 0" - /> - ) : ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError" - defaultMessage="Timeout must be less than the monitor interval" - /> - ) - } - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText" - defaultMessage="The total time allowed for testing the connection and exchanging data." - /> - } - > - <EuiFieldNumber - min={0} - value={fields[ConfigKeys.TIMEOUT]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.TIMEOUT, - }) - } - step={'any'} - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label" - defaultMessage="Tags" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText" - defaultMessage="A list of tags that will be sent with the monitor event. Press enter to add a new tag. Displayed in Uptime and enables searching by tag." - /> - } - > - <ComboBox - selectedOptions={fields[ConfigKeys.TAGS]} - onChange={(value) => handleInputChange({ value, configKey: ConfigKeys.TAGS })} - data-test-subj="syntheticsTags" - /> - </EuiFormRow> + <CommonFields fields={fields} onChange={handleInputChange} validate={validate} /> </> ); }); diff --git a/x-pack/plugins/uptime/public/components/fleet_package/icmp/simple_fields.tsx b/x-pack/plugins/uptime/public/components/fleet_package/icmp/simple_fields.tsx index 92afe4c5072e1..32c843f1ce114 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/icmp/simple_fields.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/icmp/simple_fields.tsx @@ -10,9 +10,9 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; import { ConfigKeys, Validation } from '../types'; import { useICMPSimpleFieldsContext } from '../contexts'; -import { ComboBox } from '../combo_box'; import { OptionalLabel } from '../optional_label'; import { ScheduleField } from '../schedule_field'; +import { CommonFields } from '../common/common_fields'; interface Props { validate: Validation; @@ -113,93 +113,7 @@ export const ICMPSimpleFields = memo<Props>(({ validate }) => { step={'any'} /> </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label" - defaultMessage="APM service name" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText" - defaultMessage="APM service name for this monitor. Corresponds to the service.name ECS field. Set this when monitoring an app that is also using APM to enable integrations between Uptime and APM data in Kibana." - /> - } - > - <EuiFieldText - value={fields[ConfigKeys.APM_SERVICE_NAME]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.APM_SERVICE_NAME, - }) - } - data-test-subj="syntheticsAPMServiceName" - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label" - defaultMessage="Timeout in seconds" - /> - } - isInvalid={!!validate[ConfigKeys.TIMEOUT]?.(fields)} - error={ - parseInt(fields[ConfigKeys.TIMEOUT], 10) < 0 ? ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError" - defaultMessage="Timeout must be greater than or equal to 0" - /> - ) : ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError" - defaultMessage="Timeout must be less than the monitor interval" - /> - ) - } - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText" - defaultMessage="The total time allowed for testing the connection and exchanging data." - /> - } - > - <EuiFieldNumber - min={0} - value={fields[ConfigKeys.TIMEOUT]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.TIMEOUT, - }) - } - step={'any'} - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label" - defaultMessage="Tags" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText" - defaultMessage="A list of tags that will be sent with the monitor event. Press enter to add a new tag. Displayed in Uptime and enables searching by tag." - /> - } - > - <ComboBox - selectedOptions={fields[ConfigKeys.TAGS]} - onChange={(value) => handleInputChange({ value, configKey: ConfigKeys.TAGS })} - data-test-subj="syntheticsTags" - /> - </EuiFormRow> + <CommonFields fields={fields} onChange={handleInputChange} validate={validate} /> </> ); }); diff --git a/x-pack/plugins/uptime/public/components/fleet_package/tcp/simple_fields.tsx b/x-pack/plugins/uptime/public/components/fleet_package/tcp/simple_fields.tsx index 37f0c82595e02..53a0074a47d73 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/tcp/simple_fields.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/tcp/simple_fields.tsx @@ -7,12 +7,11 @@ import React, { memo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; +import { EuiFormRow, EuiFieldText } from '@elastic/eui'; import { ConfigKeys, Validation } from '../types'; import { useTCPSimpleFieldsContext } from '../contexts'; -import { ComboBox } from '../combo_box'; -import { OptionalLabel } from '../optional_label'; import { ScheduleField } from '../schedule_field'; +import { CommonFields } from '../common/common_fields'; interface Props { validate: Validation; @@ -80,93 +79,7 @@ export const TCPSimpleFields = memo<Props>(({ validate }) => { unit={fields[ConfigKeys.SCHEDULE].unit} /> </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label" - defaultMessage="APM service name" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText" - defaultMessage="APM service name for this monitor. Corresponds to the service.name ECS field. Set this when monitoring an app that is also using APM to enable integrations between Uptime and APM data in Kibana." - /> - } - > - <EuiFieldText - value={fields[ConfigKeys.APM_SERVICE_NAME]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.APM_SERVICE_NAME, - }) - } - data-test-subj="syntheticsAPMServiceName" - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label" - defaultMessage="Timeout in seconds" - /> - } - isInvalid={!!validate[ConfigKeys.TIMEOUT]?.(fields)} - error={ - parseInt(fields[ConfigKeys.TIMEOUT], 10) < 0 ? ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError" - defaultMessage="Timeout must be greater than or equal to 0" - /> - ) : ( - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError" - defaultMessage="Timeout must be less than the monitor interval" - /> - ) - } - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText" - defaultMessage="The total time allowed for testing the connection and exchanging data." - /> - } - > - <EuiFieldNumber - min={0} - value={fields[ConfigKeys.TIMEOUT]} - onChange={(event) => - handleInputChange({ - value: event.target.value, - configKey: ConfigKeys.TIMEOUT, - }) - } - step={'any'} - /> - </EuiFormRow> - <EuiFormRow - label={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label" - defaultMessage="Tags" - /> - } - labelAppend={<OptionalLabel />} - helpText={ - <FormattedMessage - id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText" - defaultMessage="A list of tags that will be sent with the monitor event. Press enter to add a new tag. Displayed in Uptime and enables searching by tag." - /> - } - > - <ComboBox - selectedOptions={fields[ConfigKeys.TAGS]} - onChange={(value) => handleInputChange({ value, configKey: ConfigKeys.TAGS })} - data-test-subj="syntheticsTags" - /> - </EuiFormRow> + <CommonFields fields={fields} onChange={handleInputChange} validate={validate} /> </> ); }); diff --git a/x-pack/plugins/uptime/public/components/fleet_package/types.tsx b/x-pack/plugins/uptime/public/components/fleet_package/types.tsx index 89581bf993339..db736f1bae4d2 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/types.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/types.tsx @@ -76,9 +76,13 @@ export enum ScreenshotOption { export enum ConfigKeys { APM_SERVICE_NAME = 'service.name', HOSTS = 'hosts', + IGNORE_HTTPS_ERRORS = 'ignore_https_errors', + JOURNEY_FILTERS_MATCH = 'filter_journeys.match', + JOURNEY_FILTERS_TAGS = 'filter_journeys.tags', MAX_REDIRECTS = 'max_redirects', MONITOR_TYPE = 'type', NAME = 'name', + PARAMS = 'params', PASSWORD = 'password', PROXY_URL = 'proxy_url', PROXY_USE_LOCAL_RESOLVER = 'proxy_use_local_resolver', @@ -101,7 +105,6 @@ export enum ConfigKeys { SOURCE_ZIP_PASSWORD = 'source.zip_url.password', SOURCE_ZIP_FOLDER = 'source.zip_url.folder', SYNTHETICS_ARGS = 'synthetics_args', - PARAMS = 'params', TLS_CERTIFICATE_AUTHORITIES = 'ssl.certificate_authorities', TLS_CERTIFICATE = 'ssl.certificate', TLS_KEY = 'ssl.key', @@ -198,6 +201,9 @@ export type IBrowserSimpleFields = { export interface IBrowserAdvancedFields { [ConfigKeys.SYNTHETICS_ARGS]: string[]; [ConfigKeys.SCREENSHOTS]: string; + [ConfigKeys.JOURNEY_FILTERS_MATCH]: string; + [ConfigKeys.JOURNEY_FILTERS_TAGS]: string[]; + [ConfigKeys.IGNORE_HTTPS_ERRORS]: boolean; } export type HTTPFields = IHTTPSimpleFields & IHTTPAdvancedFields & ITLSFields; diff --git a/x-pack/plugins/uptime/public/components/monitor/status_details/availability_reporting/location_status_tags.test.tsx b/x-pack/plugins/uptime/public/components/monitor/status_details/availability_reporting/location_status_tags.test.tsx index 3db2efd098082..c6309debdde1f 100644 --- a/x-pack/plugins/uptime/public/components/monitor/status_details/availability_reporting/location_status_tags.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/status_details/availability_reporting/location_status_tags.test.tsx @@ -13,12 +13,6 @@ import { render } from '../../../../lib/helper/rtl_helpers'; mockMoment(); -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - describe('LocationStatusTags component', () => { let monitorLocations: MonitorLocation[]; diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx index 703e2653ff0aa..80b1463ac2f43 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx @@ -23,12 +23,6 @@ import { mockMoment } from '../../../lib/helper/test_helpers'; import { render } from '../../../lib/helper/rtl_helpers'; import { NO_DATA_MESSAGE } from './translations'; -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { - return { - htmlIdGenerator: () => () => `generated-id`, - }; -}); - const testFooPings: Ping[] = [ makePing({ docId: 'foo1', diff --git a/x-pack/plugins/uptime/public/state/api/alert_actions.ts b/x-pack/plugins/uptime/public/state/api/alert_actions.ts index b0f5f3ea490e5..40a7af18ac906 100644 --- a/x-pack/plugins/uptime/public/state/api/alert_actions.ts +++ b/x-pack/plugins/uptime/public/state/api/alert_actions.ts @@ -189,6 +189,8 @@ function getServiceNowActionParams(): ServiceNowActionParams { category: null, subcategory: null, externalId: null, + correlation_id: null, + correlation_display: null, }, comments: [], }, diff --git a/x-pack/plugins/xpack_legacy/README.md b/x-pack/plugins/xpack_legacy/README.md deleted file mode 100644 index be43825347959..0000000000000 --- a/x-pack/plugins/xpack_legacy/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Xpack Leagcy - -Contains HTTP endpoints and UiSettings that are slated for removal. diff --git a/x-pack/plugins/xpack_legacy/jest.config.js b/x-pack/plugins/xpack_legacy/jest.config.js deleted file mode 100644 index 5ad0fa36264d1..0000000000000 --- a/x-pack/plugins/xpack_legacy/jest.config.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../../..', - roots: ['<rootDir>/x-pack/plugins/xpack_legacy'], - coverageDirectory: '<rootDir>/target/kibana-coverage/jest/x-pack/plugins/xpack_legacy', - coverageReporters: ['text', 'html'], - collectCoverageFrom: ['<rootDir>/x-pack/plugins/xpack_legacy/server/**/*.{ts,tsx}'], -}; diff --git a/x-pack/plugins/xpack_legacy/kibana.json b/x-pack/plugins/xpack_legacy/kibana.json deleted file mode 100644 index 9dd0ac8340183..0000000000000 --- a/x-pack/plugins/xpack_legacy/kibana.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "xpackLegacy", - "owner": { - "name": "Kibana Core", - "githubTeam": "kibana-core" - }, - "version": "8.0.0", - "kibanaVersion": "kibana", - "server": true, - "ui": false, - "requiredPlugins": ["usageCollection"] -} diff --git a/x-pack/plugins/xpack_legacy/server/plugin.ts b/x-pack/plugins/xpack_legacy/server/plugin.ts deleted file mode 100644 index ffef7117bbbd8..0000000000000 --- a/x-pack/plugins/xpack_legacy/server/plugin.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - CoreStart, - CoreSetup, - Plugin, - PluginInitializerContext, -} from '../../../../src/core/server'; -import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server'; -import { registerSettingsRoute } from './routes/settings'; - -interface SetupPluginDeps { - usageCollection: UsageCollectionSetup; -} - -export class XpackLegacyPlugin implements Plugin { - constructor(private readonly initContext: PluginInitializerContext) {} - - public setup(core: CoreSetup, { usageCollection }: SetupPluginDeps) { - const router = core.http.createRouter(); - const globalConfig = this.initContext.config.legacy.get(); - const serverInfo = core.http.getServerInfo(); - - registerSettingsRoute({ - router, - usageCollection, - overallStatus$: core.status.overall$, - config: { - kibanaIndex: globalConfig.kibana.index, - kibanaVersion: this.initContext.env.packageInfo.version, - uuid: this.initContext.env.instanceUuid, - server: serverInfo, - }, - }); - } - - public start(core: CoreStart) {} - - public stop() {} -} diff --git a/x-pack/plugins/xpack_legacy/server/routes/settings.test.ts b/x-pack/plugins/xpack_legacy/server/routes/settings.test.ts deleted file mode 100644 index f265ea6ab125a..0000000000000 --- a/x-pack/plugins/xpack_legacy/server/routes/settings.test.ts +++ /dev/null @@ -1,115 +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 { BehaviorSubject } from 'rxjs'; -import { UnwrapPromise } from '@kbn/utility-types'; -import supertest from 'supertest'; - -import { ServiceStatus, ServiceStatusLevels } from '../../../../../src/core/server'; -import { - contextServiceMock, - elasticsearchServiceMock, - savedObjectsServiceMock, - executionContextServiceMock, -} from '../../../../../src/core/server/mocks'; -import { createHttpServer } from '../../../../../src/core/server/test_utils'; -import { registerSettingsRoute } from './settings'; - -type HttpService = ReturnType<typeof createHttpServer>; -type HttpSetup = UnwrapPromise<ReturnType<HttpService['setup']>>; - -export function mockGetClusterInfo(clusterInfo: any) { - const esClient = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; - // @ts-ignore we only care about the response body - esClient.info.mockResolvedValue({ body: { ...clusterInfo } }); - return esClient; -} - -describe('/api/settings', () => { - let server: HttpService; - let httpSetup: HttpSetup; - let overallStatus$: BehaviorSubject<ServiceStatus>; - - beforeEach(async () => { - server = createHttpServer(); - await server.preboot({ context: contextServiceMock.createPrebootContract() }); - httpSetup = await server.setup({ - context: contextServiceMock.createSetupContract({ - core: { - elasticsearch: { - client: { - asCurrentUser: mockGetClusterInfo({ cluster_uuid: 'yyy-yyyyy' }), - }, - }, - savedObjects: { - client: savedObjectsServiceMock.create(), - }, - }, - }), - executionContext: executionContextServiceMock.createInternalSetupContract(), - }); - - overallStatus$ = new BehaviorSubject<ServiceStatus>({ - level: ServiceStatusLevels.available, - summary: 'everything is working', - }); - - const usageCollection = { - getCollectorByType: jest.fn().mockReturnValue({ - fetch: jest - .fn() - .mockReturnValue({ xpack: { default_admin_email: 'kibana-machine@elastic.co' } }), - }), - } as any; - - const router = httpSetup.createRouter(''); - registerSettingsRoute({ - router, - overallStatus$, - usageCollection, - config: { - kibanaIndex: '.kibana-test', - kibanaVersion: '8.8.8-SNAPSHOT', - server: { - name: 'mykibana', - hostname: 'mykibana.com', - port: 1234, - }, - uuid: 'xxx-xxxxx', - }, - }); - - await server.start(); - }); - - afterEach(async () => { - await server.stop(); - }); - - it('successfully returns data', async () => { - const response = await supertest(httpSetup.server.listener).get('/api/settings').expect(200); - expect(response.body).toMatchObject({ - cluster_uuid: 'yyy-yyyyy', - settings: { - xpack: { - default_admin_email: 'kibana-machine@elastic.co', - }, - kibana: { - uuid: 'xxx-xxxxx', - name: 'mykibana', - index: '.kibana-test', - host: 'mykibana.com', - locale: 'en', - transport_address: `mykibana.com:1234`, - version: '8.8.8', - snapshot: true, - status: 'green', - }, - }, - }); - }); -}); diff --git a/x-pack/plugins/xpack_legacy/server/routes/settings.ts b/x-pack/plugins/xpack_legacy/server/routes/settings.ts deleted file mode 100644 index b9052ca0c84e3..0000000000000 --- a/x-pack/plugins/xpack_legacy/server/routes/settings.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { Observable } from 'rxjs'; -import { first } from 'rxjs/operators'; - -import { IRouter, ServiceStatus, ServiceStatusLevels } from '../../../../../src/core/server'; -import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/server'; -import { KIBANA_SETTINGS_TYPE } from '../../../monitoring/common/constants'; -import { KibanaSettingsCollector } from '../../../monitoring/server'; - -const SNAPSHOT_REGEX = /-snapshot/i; - -export function registerSettingsRoute({ - router, - usageCollection, - overallStatus$, - config, -}: { - router: IRouter; - usageCollection: UsageCollectionSetup; - overallStatus$: Observable<ServiceStatus>; - config: { - kibanaIndex: string; - kibanaVersion: string; - uuid: string; - server: { - name: string; - hostname: string; - port: number; - }; - }; -}) { - router.get( - { - path: '/api/settings', - validate: false, - }, - async (context, req, res) => { - const collectorFetchContext = { - esClient: context.core.elasticsearch.client.asCurrentUser, - soClient: context.core.savedObjects.client, - }; - - const settingsCollector = usageCollection.getCollectorByType(KIBANA_SETTINGS_TYPE) as - | KibanaSettingsCollector - | undefined; - if (!settingsCollector) { - throw new Error('The settings collector is not registered'); - } - - const settings = - (await settingsCollector.fetch(collectorFetchContext)) ?? - settingsCollector.getEmailValueStructure(null); - - const { body } = await collectorFetchContext.esClient.info({ filter_path: 'cluster_uuid' }); - const uuid: string = body.cluster_uuid; - - const overallStatus = await overallStatus$.pipe(first()).toPromise(); - - const kibana = { - uuid: config.uuid, - name: config.server.name, - index: config.kibanaIndex, - host: config.server.hostname, - port: config.server.port, - locale: i18n.getLocale(), - transport_address: `${config.server.hostname}:${config.server.port}`, - version: config.kibanaVersion.replace(SNAPSHOT_REGEX, ''), - snapshot: SNAPSHOT_REGEX.test(config.kibanaVersion), - status: ServiceStatusToLegacyState[overallStatus.level.toString()], - }; - return res.ok({ - body: { - cluster_uuid: uuid, - settings: { - ...settings, - kibana, - }, - }, - }); - } - ); -} - -const ServiceStatusToLegacyState: Record<string, string> = { - [ServiceStatusLevels.critical.toString()]: 'red', - [ServiceStatusLevels.unavailable.toString()]: 'red', - [ServiceStatusLevels.degraded.toString()]: 'yellow', - [ServiceStatusLevels.available.toString()]: 'green', -}; diff --git a/x-pack/plugins/xpack_legacy/tsconfig.json b/x-pack/plugins/xpack_legacy/tsconfig.json deleted file mode 100644 index 57fccc031a0cf..0000000000000 --- a/x-pack/plugins/xpack_legacy/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true - }, - "include": [ - "server/**/*", - ], - "references": [ - { "path": "../../../src/core/tsconfig.json" }, - { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, - { "path": "../monitoring/tsconfig.json" }, - ] -} diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 87eb866b14fa5..0618d379dc77d 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -34,6 +34,7 @@ const enabledActionTypes = [ '.swimlane', '.server-log', '.servicenow', + '.servicenow-sir', '.jira', '.resilient', '.slack', diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts index 997f36020af8c..ecfd8ef3b8e52 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts @@ -42,14 +42,6 @@ export function getAllExternalServiceSimulatorPaths(): string[] { const allPaths = Object.values(ExternalServiceSimulator).map((service) => getExternalServiceSimulatorPath(service) ); - allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.SERVICENOW}/api/now/v2/table/incident`); - allPaths.push( - `/api/_${NAME}/${ExternalServiceSimulator.SERVICENOW}/api/now/v2/table/incident/123` - ); - allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.SERVICENOW}/api/now/v2/table/sys_choice`); - allPaths.push( - `/api/_${NAME}/${ExternalServiceSimulator.SERVICENOW}/api/now/v2/table/sys_dictionary` - ); allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.JIRA}/rest/api/2/issue`); allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.JIRA}/rest/api/2/createmeta`); allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.RESILIENT}/rest/orgs/201/incidents`); @@ -76,6 +68,10 @@ export async function getSwimlaneServer(): Promise<http.Server> { return await initSwimlane(); } +export async function getServiceNowServer(): Promise<http.Server> { + return await initServiceNow(); +} + interface FixtureSetupDeps { actions: ActionsPluginSetupContract; features: FeaturesPluginSetup; @@ -127,7 +123,6 @@ export class FixturePlugin implements Plugin<void, void, FixtureSetupDeps, Fixtu const router: IRouter = core.http.createRouter(); initPagerduty(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.PAGERDUTY)); - initServiceNow(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW)); initJira(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.JIRA)); initResilient(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.RESILIENT)); initMSExchange(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.MS_EXCHANGE)); diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts index 8b8eb46989787..19a789659fd7f 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts @@ -5,185 +5,178 @@ * 2.0. */ -import { schema } from '@kbn/config-schema'; -import { - RequestHandlerContext, - KibanaRequest, - KibanaResponseFactory, - IKibanaResponse, - IRouter, -} from 'kibana/server'; - -export function initPlugin(router: IRouter, path: string) { - router.post( - { - path: `${path}/api/now/v2/table/incident`, - options: { - authRequired: false, - }, - validate: { - body: schema.object({ - short_description: schema.string(), - description: schema.maybe(schema.string()), - comments: schema.maybe(schema.string()), - caller_id: schema.string(), - severity: schema.string({ defaultValue: '1' }), - urgency: schema.string({ defaultValue: '1' }), - impact: schema.string({ defaultValue: '1' }), - category: schema.maybe(schema.string()), - subcategory: schema.maybe(schema.string()), - }), - }, - }, - // ServiceNow simulator: create a servicenow action pointing here, and you can get - // different responses based on the message posted. See the README.md for - // more info. - async function ( - context: RequestHandlerContext, - req: KibanaRequest<any, any, any, any>, - res: KibanaResponseFactory - ): Promise<IKibanaResponse<any>> { - return jsonResponse(res, 200, { - result: { sys_id: '123', number: 'INC01', sys_created_on: '2020-03-10 12:24:20' }, - }); - } - ); +import http from 'http'; - router.patch( - { - path: `${path}/api/now/v2/table/incident/{id}`, - options: { - authRequired: false, - }, - validate: {}, - }, - async function ( - context: RequestHandlerContext, - req: KibanaRequest<any, any, any, any>, - res: KibanaResponseFactory - ): Promise<IKibanaResponse<any>> { - return jsonResponse(res, 200, { - result: { sys_id: '123', number: 'INC01', sys_updated_on: '2020-03-10 12:24:20' }, - }); +export const initPlugin = async () => http.createServer(handler); + +const sendResponse = (response: http.ServerResponse, data: any) => { + response.statusCode = 200; + response.setHeader('Content-Type', 'application/json'); + response.end(JSON.stringify(data, null, 4)); +}; + +const handler = async (request: http.IncomingMessage, response: http.ServerResponse) => { + const buffers = []; + let data: Record<string, unknown> = {}; + + if (request.method === 'POST') { + for await (const chunk of request) { + buffers.push(chunk); } - ); - router.get( - { - path: `${path}/api/now/v2/table/incident/{id}`, - options: { - authRequired: false, + data = JSON.parse(Buffer.concat(buffers).toString()); + } + + const pathName = request.url!; + + if (pathName.includes('elastic_api/health')) { + return sendResponse(response, { + result: { + name: 'Elastic', + scope: 'x_elas2_inc_int', + version: '1.0.0', }, - validate: {}, - }, - async function ( - context: RequestHandlerContext, - req: KibanaRequest<any, any, any, any>, - res: KibanaResponseFactory - ): Promise<IKibanaResponse<any>> { - return jsonResponse(res, 200, { - result: { + }); + } + + // Import Set API: Create or update incident + if ( + pathName.includes('x_elas2_inc_int_elastic_incident') || + pathName.includes('x_elas2_sir_int_elastic_si_incident') + ) { + const update = data?.elastic_incident_id != null; + return sendResponse(response, { + import_set: 'ISET01', + staging_table: 'x_elas2_inc_int_elastic_incident', + result: [ + { + transform_map: 'Elastic Incident', + table: 'incident', + display_name: 'number', + display_value: 'INC01', + record_link: '/api/now/table/incident/1', + status: update ? 'updated' : 'inserted', sys_id: '123', - number: 'INC01', - sys_created_on: '2020-03-10 12:24:20', - short_description: 'title', - description: 'description', }, - }); - } - ); + ], + }); + } - router.get( - { - path: `${path}/api/now/v2/table/sys_dictionary`, - options: { - authRequired: false, + // Create incident + if ( + pathName === '/api/now/v2/table/incident' || + pathName === '/api/now/v2/table/sn_si_incident' + ) { + return sendResponse(response, { + result: { sys_id: '123', number: 'INC01', sys_created_on: '2020-03-10 12:24:20' }, + }); + } + + // URLs of type /api/now/v2/table/incident/{id} + // GET incident, PATCH incident + if ( + pathName.includes('/api/now/v2/table/incident') || + pathName.includes('/api/now/v2/table/sn_si_incident') + ) { + return sendResponse(response, { + result: { + sys_id: '123', + number: 'INC01', + sys_created_on: '2020-03-10 12:24:20', + sys_updated_on: '2020-03-10 12:24:20', }, - validate: {}, - }, - async function ( - context: RequestHandlerContext, - req: KibanaRequest<any, any, any, any>, - res: KibanaResponseFactory - ): Promise<IKibanaResponse<any>> { - return jsonResponse(res, 200, { - result: [ - { - column_label: 'Close notes', - mandatory: 'false', - max_length: '4000', - element: 'close_notes', - }, - { - column_label: 'Description', - mandatory: 'false', - max_length: '4000', - element: 'description', - }, - { - column_label: 'Short description', - mandatory: 'false', - max_length: '160', - element: 'short_description', - }, - ], - }); - } - ); + }); + } - router.get( - { - path: `${path}/api/now/v2/table/sys_choice`, - options: { - authRequired: false, + // Add multiple observables + if (pathName.includes('/observables/bulk')) { + return sendResponse(response, { + result: [ + { + value: '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9', + observable_sys_id: '1', + }, + { + value: '127.0.0.1', + observable_sys_id: '2', + }, + { + value: 'https://example.com', + observable_sys_id: '3', + }, + ], + }); + } + + // Add single observables + if (pathName.includes('/observables')) { + return sendResponse(response, { + result: { + value: '127.0.0.1', + observable_sys_id: '2', }, - validate: {}, - }, - async function ( - context: RequestHandlerContext, - req: KibanaRequest<any, any, any, any>, - res: KibanaResponseFactory - ): Promise<IKibanaResponse<any>> { - return jsonResponse(res, 200, { - result: [ - { - dependent_value: '', - label: '1 - Critical', - value: '1', - }, - { - dependent_value: '', - label: '2 - High', - value: '2', - }, - { - dependent_value: '', - label: '3 - Moderate', - value: '3', - }, - { - dependent_value: '', - label: '4 - Low', - value: '4', - }, - { - dependent_value: '', - label: '5 - Planning', - value: '5', - }, - ], - }); - } - ); -} - -function jsonResponse(res: KibanaResponseFactory, code: number, object?: Record<string, unknown>) { - if (object == null) { - return res.custom({ - statusCode: code, - body: '', }); } - return res.custom<Record<string, unknown>>({ body: object, statusCode: code }); -} + if (pathName.includes('/api/now/table/sys_dictionary')) { + return sendResponse(response, { + result: [ + { + column_label: 'Close notes', + mandatory: 'false', + max_length: '4000', + element: 'close_notes', + }, + { + column_label: 'Description', + mandatory: 'false', + max_length: '4000', + element: 'description', + }, + { + column_label: 'Short description', + mandatory: 'false', + max_length: '160', + element: 'short_description', + }, + ], + }); + } + + if (pathName.includes('/api/now/table/sys_choice')) { + return sendResponse(response, { + result: [ + { + dependent_value: '', + label: '1 - Critical', + value: '1', + }, + { + dependent_value: '', + label: '2 - High', + value: '2', + }, + { + dependent_value: '', + label: '3 - Moderate', + value: '3', + }, + { + dependent_value: '', + label: '4 - Low', + value: '4', + }, + { + dependent_value: '', + label: '5 - Planning', + value: '5', + }, + ], + }); + } + + // Return an 400 error if endpoint is not supported + response.statusCode = 400; + response.setHeader('Content-Type', 'application/json'); + response.end('Not supported endpoint to request servicenow simulator'); +}; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/swimlane_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/swimlane_simulation.ts index afba550908ddc..97cbcbe7a60a6 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/swimlane_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/swimlane_simulation.ts @@ -35,5 +35,5 @@ const handler = (request: http.IncomingMessage, response: http.ServerResponse) = // Return an 400 error if http method is not supported response.statusCode = 400; response.setHeader('Content-Type', 'application/json'); - response.end('Not supported http method to request slack simulator'); + response.end('Not supported http method to request swimlane simulator'); }; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts similarity index 76% rename from x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts rename to x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts index d6196ee6ce312..fe1ebdf8d28a9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts @@ -7,24 +7,22 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import getPort from 'get-port'; +import http from 'http'; import { getHttpProxyServer } from '../../../../common/lib/get_proxy_server'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; - -import { - getExternalServiceSimulatorPath, - ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin'; +import { getServiceNowServer } from '../../../../common/fixtures/plugins/actions_simulators/server/plugin'; // eslint-disable-next-line import/no-default-export -export default function servicenowTest({ getService }: FtrProviderContext) { +export default function serviceNowITSMTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - const kibanaServer = getService('kibanaServer'); const configService = getService('config'); const mockServiceNow = { config: { apiUrl: 'www.servicenowisinkibanaactions.com', + isLegacy: false, }, secrets: { password: 'elastic', @@ -41,7 +39,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { short_description: 'a title', urgency: '1', category: 'software', - subcategory: 'software', + subcategory: 'os', }, comments: [ { @@ -53,16 +51,37 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }, }; - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + describe('ServiceNow ITSM', () => { + let simulatedActionId = ''; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; + let proxyServer: httpProxy | undefined; + let proxyHaveBeenCalled = false; - describe('ServiceNow', () => { - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) + before(async () => { + serviceNowServer = await getServiceNowServer(); + const availablePort = await getPort({ port: getPort.makeRange(9000, 9100) }); + if (!serviceNowServer.listening) { + serviceNowServer.listen(availablePort); + } + serviceNowSimulatorURL = `http://localhost:${availablePort}`; + proxyServer = await getHttpProxyServer( + serviceNowSimulatorURL, + configService.get('kbnTestServer.serverArgs'), + () => { + proxyHaveBeenCalled = true; + } ); }); - describe('ServiceNow - Action Creation', () => { + after(() => { + serviceNowServer.close(); + if (proxyServer) { + proxyServer.close(); + } + }); + + describe('ServiceNow ITSM - Action Creation', () => { it('should return 200 when creating a servicenow action successfully', async () => { const { body: createdAction } = await supertest .post('/api/actions/connector') @@ -71,7 +90,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { name: 'A servicenow action', connector_type_id: '.servicenow', config: { - apiUrl: servicenowSimulatorURL, + apiUrl: serviceNowSimulatorURL, }, secrets: mockServiceNow.secrets, }) @@ -84,7 +103,8 @@ export default function servicenowTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', is_missing_secrets: false, config: { - apiUrl: servicenowSimulatorURL, + apiUrl: serviceNowSimulatorURL, + isLegacy: false, }, }); @@ -99,11 +119,33 @@ export default function servicenowTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', is_missing_secrets: false, config: { - apiUrl: servicenowSimulatorURL, + apiUrl: serviceNowSimulatorURL, + isLegacy: false, }, }); }); + it('should set the isLegacy to false when not provided', async () => { + const { body: createdAction } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow', + config: { + apiUrl: serviceNowSimulatorURL, + }, + secrets: mockServiceNow.secrets, + }) + .expect(200); + + const { body: fetchedAction } = await supertest + .get(`/api/actions/connector/${createdAction.id}`) + .expect(200); + + expect(fetchedAction.config.isLegacy).to.be(false); + }); + it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { await supertest .post('/api/actions/connector') @@ -155,7 +197,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { name: 'A servicenow action', connector_type_id: '.servicenow', config: { - apiUrl: servicenowSimulatorURL, + apiUrl: serviceNowSimulatorURL, }, }) .expect(400) @@ -170,10 +212,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }); }); - describe('ServiceNow - Executor', () => { - let simulatedActionId: string; - let proxyServer: httpProxy | undefined; - let proxyHaveBeenCalled = false; + describe('ServiceNow ITSM - Executor', () => { before(async () => { const { body } = await supertest .post('/api/actions/connector') @@ -182,19 +221,12 @@ export default function servicenowTest({ getService }: FtrProviderContext) { name: 'A servicenow simulator', connector_type_id: '.servicenow', config: { - apiUrl: servicenowSimulatorURL, + apiUrl: serviceNowSimulatorURL, + isLegacy: false, }, secrets: mockServiceNow.secrets, }); simulatedActionId = body.id; - - proxyServer = await getHttpProxyServer( - kibanaServer.resolveUrl('/'), - configService.get('kbnTestServer.serverArgs'), - () => { - proxyHaveBeenCalled = true; - } - ); }); describe('Validation', () => { @@ -377,31 +409,81 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }); describe('Execution', () => { - it('should handle creating an incident without comments', async () => { - const { body: result } = await supertest - .post(`/api/actions/connector/${simulatedActionId}/_execute`) - .set('kbn-xsrf', 'foo') - .send({ - params: { - ...mockServiceNow.params, - subActionParams: { - incident: mockServiceNow.params.subActionParams.incident, - comments: [], + // New connectors + describe('Import set API', () => { + it('should handle creating an incident without comments', async () => { + const { body: result } = await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + incident: mockServiceNow.params.subActionParams.incident, + comments: [], + }, }, + }) + .expect(200); + + expect(proxyHaveBeenCalled).to.equal(true); + expect(result).to.eql({ + status: 'ok', + connector_id: simulatedActionId, + data: { + id: '123', + title: 'INC01', + pushedDate: '2020-03-10T12:24:20.000Z', + url: `${serviceNowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, }, - }) - .expect(200); - - expect(proxyHaveBeenCalled).to.equal(true); - expect(result).to.eql({ - status: 'ok', - connector_id: simulatedActionId, - data: { - id: '123', - title: 'INC01', - pushedDate: '2020-03-10T12:24:20.000Z', - url: `${servicenowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, - }, + }); + }); + }); + + // Legacy connectors + describe('Table API', () => { + before(async () => { + const { body } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow simulator', + connector_type_id: '.servicenow', + config: { + apiUrl: serviceNowSimulatorURL, + isLegacy: true, + }, + secrets: mockServiceNow.secrets, + }); + simulatedActionId = body.id; + }); + + it('should handle creating an incident without comments', async () => { + const { body: result } = await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + incident: mockServiceNow.params.subActionParams.incident, + comments: [], + }, + }, + }) + .expect(200); + + expect(proxyHaveBeenCalled).to.equal(true); + expect(result).to.eql({ + status: 'ok', + connector_id: simulatedActionId, + data: { + id: '123', + title: 'INC01', + pushedDate: '2020-03-10T12:24:20.000Z', + url: `${serviceNowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, + }, + }); }); }); @@ -453,12 +535,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }); }); }); - - after(() => { - if (proxyServer) { - proxyServer.close(); - } - }); }); }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts new file mode 100644 index 0000000000000..eee3425b6a61f --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts @@ -0,0 +1,544 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import httpProxy from 'http-proxy'; +import expect from '@kbn/expect'; +import getPort from 'get-port'; +import http from 'http'; + +import { getHttpProxyServer } from '../../../../common/lib/get_proxy_server'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { getServiceNowServer } from '../../../../common/fixtures/plugins/actions_simulators/server/plugin'; + +// eslint-disable-next-line import/no-default-export +export default function serviceNowSIRTest({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const configService = getService('config'); + + const mockServiceNow = { + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + isLegacy: false, + }, + secrets: { + password: 'elastic', + username: 'changeme', + }, + params: { + subAction: 'pushToService', + subActionParams: { + incident: { + externalId: null, + short_description: 'Incident title', + description: 'Incident description', + dest_ip: ['192.168.1.1', '192.168.1.3'], + source_ip: ['192.168.1.2', '192.168.1.4'], + malware_hash: ['5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9'], + malware_url: ['https://example.com'], + category: 'software', + subcategory: 'os', + correlation_id: 'alertID', + correlation_display: 'Alerting', + priority: '1', + }, + comments: [ + { + comment: 'first comment', + commentId: '456', + }, + ], + }, + }, + }; + + describe('ServiceNow SIR', () => { + let simulatedActionId = ''; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; + let proxyServer: httpProxy | undefined; + let proxyHaveBeenCalled = false; + + before(async () => { + serviceNowServer = await getServiceNowServer(); + const availablePort = await getPort({ port: getPort.makeRange(9000, 9100) }); + if (!serviceNowServer.listening) { + serviceNowServer.listen(availablePort); + } + serviceNowSimulatorURL = `http://localhost:${availablePort}`; + proxyServer = await getHttpProxyServer( + serviceNowSimulatorURL, + configService.get('kbnTestServer.serverArgs'), + () => { + proxyHaveBeenCalled = true; + } + ); + }); + + after(() => { + serviceNowServer.close(); + if (proxyServer) { + proxyServer.close(); + } + }); + + describe('ServiceNow SIR - Action Creation', () => { + it('should return 200 when creating a servicenow action successfully', async () => { + const { body: createdAction } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + apiUrl: serviceNowSimulatorURL, + }, + secrets: mockServiceNow.secrets, + }) + .expect(200); + + expect(createdAction).to.eql({ + id: createdAction.id, + is_preconfigured: false, + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + isLegacy: false, + }, + }); + + const { body: fetchedAction } = await supertest + .get(`/api/actions/connector/${createdAction.id}`) + .expect(200); + + expect(fetchedAction).to.eql({ + id: fetchedAction.id, + is_preconfigured: false, + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + isLegacy: false, + }, + }); + }); + + it('should set the isLegacy to false when not provided', async () => { + const { body: createdAction } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + apiUrl: serviceNowSimulatorURL, + }, + secrets: mockServiceNow.secrets, + }) + .expect(200); + + const { body: fetchedAction } = await supertest + .get(`/api/actions/connector/${createdAction.id}`) + .expect(200); + + expect(fetchedAction.config.isLegacy).to.be(false); + }); + + it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: {}, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow action with a not present in allowedHosts apiUrl', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + apiUrl: 'http://servicenow.mynonexistent.com', + }, + secrets: mockServiceNow.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: error configuring connector action: target url "http://servicenow.mynonexistent.com" is not added to the Kibana config xpack.actions.allowedHosts', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow action without secrets', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + apiUrl: serviceNowSimulatorURL, + }, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type secrets: [password]: expected value of type [string] but got [undefined]', + }); + }); + }); + }); + + describe('ServiceNow SIR - Executor', () => { + before(async () => { + const { body } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow simulator', + connector_type_id: '.servicenow-sir', + config: { + apiUrl: serviceNowSimulatorURL, + isLegacy: false, + }, + secrets: mockServiceNow.secrets, + }); + simulatedActionId = body.id; + }); + + describe('Validation', () => { + it('should handle failing with a simulated success without action', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: {}, + }) + .then((resp: any) => { + expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(resp.body.connector_id).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circumstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); + }); + }); + + it('should handle failing with a simulated success without unsupported action', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { subAction: 'non-supported' }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + connector_id: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subAction]: expected value to equal [getChoices]', + }); + }); + }); + + it('should handle failing with a simulated success without subActionParams', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { subAction: 'pushToService' }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + connector_id: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.short_description]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [getChoices]', + }); + }); + }); + + it('should handle failing with a simulated success without title', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + savedObjectId: 'success', + }, + }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + connector_id: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.short_description]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [getChoices]', + }); + }); + }); + + it('should handle failing with a simulated success without commentId', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + incident: { + ...mockServiceNow.params.subActionParams.incident, + short_description: 'success', + }, + comments: [{ comment: 'boo' }], + }, + }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + connector_id: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [getChoices]', + }); + }); + }); + + it('should handle failing with a simulated success without comment message', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + incident: { + ...mockServiceNow.params.subActionParams.incident, + short_description: 'success', + }, + comments: [{ commentId: 'success' }], + }, + }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + connector_id: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [getChoices]', + }); + }); + }); + + describe('getChoices', () => { + it('should fail when field is not provided', async () => { + await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + subAction: 'getChoices', + subActionParams: {}, + }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + connector_id: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subActionParams.fields]: expected value of type [array] but got [undefined]', + }); + }); + }); + }); + }); + + describe('Execution', () => { + // New connectors + describe('Import set API', () => { + it('should handle creating an incident without comments', async () => { + const { body: result } = await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + incident: mockServiceNow.params.subActionParams.incident, + comments: [], + }, + }, + }) + .expect(200); + + expect(proxyHaveBeenCalled).to.equal(true); + expect(result).to.eql({ + status: 'ok', + connector_id: simulatedActionId, + data: { + id: '123', + title: 'INC01', + pushedDate: '2020-03-10T12:24:20.000Z', + url: `${serviceNowSimulatorURL}/nav_to.do?uri=sn_si_incident.do?sys_id=123`, + }, + }); + }); + }); + + // Legacy connectors + describe('Table API', () => { + before(async () => { + const { body } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow simulator', + connector_type_id: '.servicenow-sir', + config: { + apiUrl: serviceNowSimulatorURL, + isLegacy: true, + }, + secrets: mockServiceNow.secrets, + }); + simulatedActionId = body.id; + }); + + it('should handle creating an incident without comments', async () => { + const { body: result } = await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + ...mockServiceNow.params, + subActionParams: { + incident: mockServiceNow.params.subActionParams.incident, + comments: [], + }, + }, + }) + .expect(200); + + expect(proxyHaveBeenCalled).to.equal(true); + expect(result).to.eql({ + status: 'ok', + connector_id: simulatedActionId, + data: { + id: '123', + title: 'INC01', + pushedDate: '2020-03-10T12:24:20.000Z', + url: `${serviceNowSimulatorURL}/nav_to.do?uri=sn_si_incident.do?sys_id=123`, + }, + }); + }); + }); + + describe('getChoices', () => { + it('should get choices', async () => { + const { body: result } = await supertest + .post(`/api/actions/connector/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + subAction: 'getChoices', + subActionParams: { fields: ['priority'] }, + }, + }) + .expect(200); + + expect(proxyHaveBeenCalled).to.equal(true); + expect(result).to.eql({ + status: 'ok', + connector_id: simulatedActionId, + data: [ + { + dependent_value: '', + label: '1 - Critical', + value: '1', + }, + { + dependent_value: '', + label: '2 - High', + value: '2', + }, + { + dependent_value: '', + label: '3 - Moderate', + value: '3', + }, + { + dependent_value: '', + label: '4 - Low', + value: '4', + }, + { + dependent_value: '', + label: '5 - Planning', + value: '5', + }, + ], + }); + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts index db57af0ba1a98..61bd1bcad34ad 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts @@ -25,7 +25,8 @@ export default function actionsTests({ loadTestFile, getService }: FtrProviderCo loadTestFile(require.resolve('./builtin_action_types/pagerduty')); loadTestFile(require.resolve('./builtin_action_types/swimlane')); loadTestFile(require.resolve('./builtin_action_types/server_log')); - loadTestFile(require.resolve('./builtin_action_types/servicenow')); + loadTestFile(require.resolve('./builtin_action_types/servicenow_itsm')); + loadTestFile(require.resolve('./builtin_action_types/servicenow_sir')); loadTestFile(require.resolve('./builtin_action_types/jira')); loadTestFile(require.resolve('./builtin_action_types/resilient')); loadTestFile(require.resolve('./builtin_action_types/slack')); diff --git a/x-pack/test/api_integration/apis/index.ts b/x-pack/test/api_integration/apis/index.ts index eed39fd6dc6dc..c3d08ba306692 100644 --- a/x-pack/test/api_integration/apis/index.ts +++ b/x-pack/test/api_integration/apis/index.ts @@ -16,7 +16,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./security')); loadTestFile(require.resolve('./spaces')); loadTestFile(require.resolve('./monitoring')); - loadTestFile(require.resolve('./xpack_legacy')); loadTestFile(require.resolve('./features')); loadTestFile(require.resolve('./telemetry')); loadTestFile(require.resolve('./logstash')); diff --git a/x-pack/test/api_integration/apis/maps/get_tile.js b/x-pack/test/api_integration/apis/maps/get_tile.js index a1d4f10ca7be8..9705064464843 100644 --- a/x-pack/test/api_integration/apis/maps/get_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_tile.js @@ -66,14 +66,21 @@ export default function ({ getService }) { expect(metadataFeature.type).to.be(3); expect(metadataFeature.extent).to.be(4096); expect(metadataFeature.id).to.be(undefined); + const fieldMeta = JSON.parse(metadataFeature.properties.fieldMeta); + delete metadataFeature.properties.fieldMeta; expect(metadataFeature.properties).to.eql({ __kbn_feature_count__: 2, __kbn_is_tile_complete__: true, __kbn_metadata_feature__: true, __kbn_vector_shape_type_counts__: '{"POINT":2,"LINE":0,"POLYGON":0}', - fieldMeta: - '{"machine.os.raw":{"categories":{"categories":[{"key":"ios","count":1},{"count":1}]}},"bytes":{"range":{"min":9252,"max":9583,"delta":331},"categories":{"categories":[{"key":9252,"count":1},{"key":9583,"count":1}]}}}', }); + expect(fieldMeta.bytes.range).to.eql({ + min: 9252, + max: 9583, + delta: 331, + }); + expect(fieldMeta.bytes.categories.categories.length).to.be(2); + expect(fieldMeta['machine.os.raw'].categories.categories.length).to.be(2); expect(metadataFeature.loadGeometry()).to.eql([ [ { x: 0, y: 4096 }, diff --git a/x-pack/test/api_integration/apis/xpack_legacy/settings/settings.js b/x-pack/test/api_integration/apis/xpack_legacy/settings/settings.js deleted file mode 100644 index 6a82c5468a2c4..0000000000000 --- a/x-pack/test/api_integration/apis/xpack_legacy/settings/settings.js +++ /dev/null @@ -1,40 +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 expect from '@kbn/expect'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - describe('/api/settings', () => { - describe('with trial license clusters', () => { - const archive = 'x-pack/test/functional/es_archives/monitoring/multicluster'; - - before('load clusters archive', () => { - return esArchiver.load(archive); - }); - - after('unload clusters archive', () => { - return esArchiver.unload(archive); - }); - - it('should load multiple clusters', async () => { - const { body } = await supertest.get('/api/settings').set('kbn-xsrf', 'xxx').expect(200); - expect(body.cluster_uuid.length > 1).to.eql(true); - expect(body.settings.kibana.uuid.length > 0).to.eql(true); - expect(body.settings.kibana.name.length > 0).to.eql(true); - expect(body.settings.kibana.index.length > 0).to.eql(true); - expect(body.settings.kibana.host.length > 0).to.eql(true); - expect(body.settings.kibana.transport_address.length > 0).to.eql(true); - expect(body.settings.kibana.version.length > 0).to.eql(true); - expect(body.settings.kibana.status.length > 0).to.eql(true); - expect(body.settings.xpack.default_admin_email).to.eql(null); - }); - }); - }); -} diff --git a/x-pack/test/apm_api_integration/common/trace_data.ts b/x-pack/test/apm_api_integration/common/trace_data.ts index 9c96d3fa1e0b0..84bbb4beea4f4 100644 --- a/x-pack/test/apm_api_integration/common/trace_data.ts +++ b/x-pack/test/apm_api_integration/common/trace_data.ts @@ -6,6 +6,7 @@ */ import { + getBreakdownMetrics, getSpanDestinationMetrics, getTransactionMetrics, toElasticsearchOutput, @@ -20,7 +21,12 @@ export async function traceData(context: InheritedFtrProviderContext) { return { index: (events: any[]) => { const esEvents = toElasticsearchOutput( - events.concat(getTransactionMetrics(events)).concat(getSpanDestinationMetrics(events)), + [ + ...events, + ...getTransactionMetrics(events), + ...getSpanDestinationMetrics(events), + ...getBreakdownMetrics(events), + ], '7.14.0' ); diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts index 2d165f4ceb902..cdf62053a821b 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts @@ -8,6 +8,7 @@ import expect from '@kbn/expect'; import { pick, sortBy } from 'lodash'; import moment from 'moment'; +import { service, timerange } from '@elastic/apm-generator'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { isFiniteNumber } from '../../../../plugins/apm/common/utils/is_finite_number'; import { FtrProviderContext } from '../../common/ftr_provider_context'; @@ -15,9 +16,12 @@ import archives from '../../common/fixtures/es_archiver/archives_metadata'; import { registry } from '../../common/registry'; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types'; +import { ENVIRONMENT_ALL } from '../../../../plugins/apm/common/environment_filter_values'; +import { SERVICE_NODE_NAME_MISSING } from '../../../../plugins/apm/common/service_nodes'; export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); + const traceData = getService('traceData'); const archiveName = 'apm_8.0.0'; const { start, end } = archives[archiveName]; @@ -278,4 +282,145 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); } ); + + registry.when( + 'Service overview instances main statistics when data is generated', + { config: 'basic', archives: ['apm_8.0.0_empty'] }, + () => { + describe('for two go instances and one java instance', () => { + const GO_A_INSTANCE_RATE_SUCCESS = 10; + const GO_A_INSTANCE_RATE_FAILURE = 5; + const GO_B_INSTANCE_RATE_SUCCESS = 15; + + const JAVA_INSTANCE_RATE = 20; + + const rangeStart = new Date('2021-01-01T12:00:00.000Z').getTime(); + const rangeEnd = new Date('2021-01-01T12:15:00.000Z').getTime() - 1; + + before(async () => { + const goService = service('opbeans-go', 'production', 'go'); + const javaService = service('opbeans-java', 'production', 'java'); + + const goInstanceA = goService.instance('go-instance-a'); + const goInstanceB = goService.instance('go-instance-b'); + const javaInstance = javaService.instance('java-instance'); + + const interval = timerange(rangeStart, rangeEnd).interval('1m'); + + // include exit spans to generate span_destination metrics + // that should not be included + function withSpans(timestamp: number) { + return new Array(3).fill(undefined).map(() => + goInstanceA + .span('GET apm-*/_search', 'db', 'elasticsearch') + .timestamp(timestamp + 100) + .duration(300) + .destination('elasticsearch') + .success() + ); + } + + return traceData.index([ + ...interval.rate(GO_A_INSTANCE_RATE_SUCCESS).flatMap((timestamp) => + goInstanceA + .transaction('GET /api/product/list') + .success() + .duration(500) + .timestamp(timestamp) + .children(...withSpans(timestamp)) + .serialize() + ), + ...interval.rate(GO_A_INSTANCE_RATE_FAILURE).flatMap((timestamp) => + goInstanceA + .transaction('GET /api/product/list') + .failure() + .duration(500) + .timestamp(timestamp) + .children(...withSpans(timestamp)) + .serialize() + ), + ...interval.rate(GO_B_INSTANCE_RATE_SUCCESS).flatMap((timestamp) => + goInstanceB + .transaction('GET /api/product/list') + .success() + .duration(500) + .timestamp(timestamp) + .children(...withSpans(timestamp)) + .serialize() + ), + ...interval.rate(JAVA_INSTANCE_RATE).flatMap((timestamp) => + javaInstance + .transaction('GET /api/product/list') + .success() + .duration(500) + .timestamp(timestamp) + .children(...withSpans(timestamp)) + .serialize() + ), + ]); + }); + + after(async () => { + return traceData.clean(); + }); + + describe('for the go service', () => { + let body: APIReturnType<'GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics'>; + + before(async () => { + body = ( + await apmApiClient.readUser({ + endpoint: + 'GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics', + params: { + path: { + serviceName: 'opbeans-go', + }, + query: { + start: new Date(rangeStart).toISOString(), + end: new Date(rangeEnd + 1).toISOString(), + environment: ENVIRONMENT_ALL.value, + kuery: '', + latencyAggregationType: LatencyAggregationType.avg, + transactionType: 'request', + }, + }, + }) + ).body; + }); + + it('returns statistics for the go instances', () => { + const goAStats = body.currentPeriod.find( + (stat) => stat.serviceNodeName === 'go-instance-a' + ); + const goBStats = body.currentPeriod.find( + (stat) => stat.serviceNodeName === 'go-instance-b' + ); + + expect(goAStats?.throughput).to.eql( + GO_A_INSTANCE_RATE_SUCCESS + GO_A_INSTANCE_RATE_FAILURE + ); + + expect(goBStats?.throughput).to.eql(GO_B_INSTANCE_RATE_SUCCESS); + }); + + it('does not return data for the java service', () => { + const javaStats = body.currentPeriod.find( + (stat) => stat.serviceNodeName === 'java-instance' + ); + + expect(javaStats).to.be(undefined); + }); + + it('does not return data for missing service node name', () => { + const missingNameStats = body.currentPeriod.find( + (stat) => stat.serviceNodeName === SERVICE_NODE_NAME_MISSING + ); + + expect(missingNameStats).to.be(undefined); + }); + }); + }); + } + ); } diff --git a/x-pack/test/case_api_integration/common/lib/utils.ts b/x-pack/test/case_api_integration/common/lib/utils.ts index 7367641d71585..f34d7398db0c2 100644 --- a/x-pack/test/case_api_integration/common/lib/utils.ts +++ b/x-pack/test/case_api_integration/common/lib/utils.ts @@ -6,6 +6,9 @@ */ import { omit } from 'lodash'; +import getPort from 'get-port'; +import http from 'http'; + import expect from '@kbn/expect'; import type { ApiResponse, estypes } from '@elastic/elasticsearch'; import type { KibanaClient } from '@elastic/elasticsearch/api/kibana'; @@ -58,6 +61,7 @@ import { User } from './authentication/types'; import { superUser } from './authentication/users'; import { ESCasesConfigureAttributes } from '../../../../plugins/cases/server/services/configure/types'; import { ESCaseAttributes } from '../../../../plugins/cases/server/services/cases/types'; +import { getServiceNowServer } from '../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; function toArray<T>(input: T | T[]): T[] { if (Array.isArray(input)) { @@ -652,13 +656,13 @@ export const getCaseSavedObjectsFromES = async ({ es }: { es: KibanaClient }) => export const createCaseWithConnector = async ({ supertest, configureReq = {}, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth = { user: superUser, space: null }, createCaseReq = getPostCaseRequest(), }: { supertest: SuperTest.SuperTest<SuperTest.Test>; - servicenowSimulatorURL: string; + serviceNowSimulatorURL: string; actionsRemover: ActionsRemover; configureReq?: Record<string, unknown>; auth?: { user: User; space: string | null }; @@ -671,7 +675,7 @@ export const createCaseWithConnector = async ({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, auth, }); @@ -1220,3 +1224,17 @@ export const getAlertsAttachedToCase = async ({ return theCase; }; + +export const getServiceNowSimulationServer = async (): Promise<{ + server: http.Server; + url: string; +}> => { + const server = await getServiceNowServer(); + const port = await getPort({ port: getPort.makeRange(9000, 9100) }); + if (!server.listening) { + server.listen(port); + } + const url = `http://localhost:${port}`; + + return { server, url }; +}; diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/push_case.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/push_case.ts index 0ea66d35b63b8..73e8f2ba851fc 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/push_case.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/push_case.ts @@ -7,6 +7,8 @@ /* eslint-disable @typescript-eslint/naming-convention */ +import http from 'http'; + import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; @@ -32,11 +34,8 @@ import { getServiceNowConnector, getConnectorMappingsFromES, getCase, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { CaseConnector, CaseStatuses, @@ -55,17 +54,17 @@ import { // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); - const kibanaServer = getService('kibanaServer'); const es = getService('es'); describe('push_case', () => { const actionsRemover = new ActionsRemover(supertest); + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - let servicenowSimulatorURL: string = '<could not determine kibana url>'; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -73,10 +72,14 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should push a case', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); const theCase = await pushCase({ @@ -95,18 +98,13 @@ export default ({ getService }: FtrProviderContext): void => { external_title: 'INC01', }); - // external_url is of the form http://elastic:changeme@localhost:5620 which is different between various environments like Jekins - expect( - external_url.includes( - 'api/_actions-FTS-external-service-simulators/servicenow/nav_to.do?uri=incident.do?sys_id=123' - ) - ).to.equal(true); + expect(external_url.includes('nav_to.do?uri=incident.do?sys_id=123')).to.equal(true); }); it('preserves the connector.id after pushing a case', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); const theCase = await pushCase({ @@ -121,7 +119,7 @@ export default ({ getService }: FtrProviderContext): void => { it('preserves the external_service.connector_id after updating the connector', async () => { const { postedCase, connector: pushConnector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); @@ -135,7 +133,7 @@ export default ({ getService }: FtrProviderContext): void => { supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, }); @@ -175,7 +173,7 @@ export default ({ getService }: FtrProviderContext): void => { supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, }); @@ -222,7 +220,7 @@ export default ({ getService }: FtrProviderContext): void => { it('pushes a comment appropriately', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); await createComment({ supertest, caseId: postedCase.id, params: postCommentUserReq }); @@ -241,7 +239,7 @@ export default ({ getService }: FtrProviderContext): void => { closure_type: 'close-by-pushing', }, supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); const theCase = await pushCase({ @@ -256,7 +254,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should create the correct user action', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); const pushedCase = await pushCase({ @@ -289,7 +287,7 @@ export default ({ getService }: FtrProviderContext): void => { connector_name: connector.name, external_id: '123', external_title: 'INC01', - external_url: `${servicenowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, + external_url: `${serviceNowSimulatorURL}/nav_to.do?uri=incident.do?sys_id=123`, }); }); @@ -297,7 +295,7 @@ export default ({ getService }: FtrProviderContext): void => { it.skip('should push a collection case but not close it when closure_type: close-by-pushing', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, configureReq: { closure_type: 'close-by-pushing', @@ -337,7 +335,7 @@ export default ({ getService }: FtrProviderContext): void => { it('unhappy path = 409s when case is closed', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); await updateCase({ @@ -367,7 +365,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should push a case that the user has permissions for', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth: superUserSpace1Auth, }); @@ -383,7 +381,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should not push a case that the user does not have permissions for', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth: superUserSpace1Auth, createCaseReq: getPostCaseRequest({ owner: 'observabilityFixture' }), @@ -404,7 +402,7 @@ export default ({ getService }: FtrProviderContext): void => { } with role(s) ${user.roles.join()} - should NOT push a case`, async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth: superUserSpace1Auth, }); @@ -422,7 +420,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should not push a case in a space that the user does not have permissions for', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth: { user: superUser, space: 'space2' }, }); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts index 255a2a4ce28b5..fda2c8d361042 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts @@ -5,6 +5,7 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../common/ftr_provider_context'; @@ -17,13 +18,10 @@ import { deleteConfiguration, getConfigurationRequest, getServiceNowConnector, + getServiceNowSimulationServer, } from '../../../../../common/lib/utils'; import { ObjectRemover as ActionsRemover } from '../../../../../../alerting_api_integration/common/lib'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { getCreateConnectorUrl } from '../../../../../../../plugins/cases/common/utils/connectors_api'; // eslint-disable-next-line import/no-default-export @@ -31,15 +29,17 @@ export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); const actionsRemover = new ActionsRemover(supertest); - const kibanaServer = getService('kibanaServer'); describe('get_all_user_actions', () => { - let servicenowSimulatorURL: string = '<could not determine kibana url>'; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; + + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); + afterEach(async () => { await deleteCasesByESQuery(es); await deleteComments(es); @@ -48,13 +48,17 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it(`on new push to service, user action: 'push-to-service' should be called with actionFields: ['pushed']`, async () => { const { body: connector } = await supertest .post(getCreateConnectorUrl()) .set('kbn-xsrf', 'true') .send({ ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }) .expect(200); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts index ff8f1cff884af..404b63376daa4 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts @@ -5,14 +5,10 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; - import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { getServiceNowConnector, @@ -22,6 +18,7 @@ import { getConfigurationRequest, removeServerGeneratedPropertiesFromSavedObject, getConfigurationOutput, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; @@ -29,27 +26,31 @@ import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const actionsRemover = new ActionsRemover(supertest); - const kibanaServer = getService('kibanaServer'); describe('get_configure', () => { - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should return a configuration with mapping', async () => { const connector = await createConnector({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, }); actionsRemover.add('default', connector.id, 'action', 'actions'); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index fb922f8d10243..c3e737464f19b 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -109,6 +109,7 @@ export default ({ getService }: FtrProviderContext): void => { name: 'ServiceNow Connector', config: { apiUrl: 'http://some.non.existent.com', + isLegacy: false, }, isPreconfigured: false, isMissingSecrets: false, @@ -118,7 +119,10 @@ export default ({ getService }: FtrProviderContext): void => { id: sir.id, actionTypeId: '.servicenow-sir', name: 'ServiceNow Connector', - config: { apiUrl: 'http://some.non.existent.com' }, + config: { + apiUrl: 'http://some.non.existent.com', + isLegacy: false, + }, isPreconfigured: false, isMissingSecrets: false, referencedByCount: 0, diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts index 789b68b19beb6..26eba77dd2576 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts @@ -5,13 +5,10 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { getConfigurationRequest, @@ -22,6 +19,7 @@ import { updateConfiguration, getServiceNowConnector, createConnector, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; @@ -29,16 +27,16 @@ import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - const kibanaServer = getService('kibanaServer'); describe('patch_configure', () => { const actionsRemover = new ActionsRemover(supertest); - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -46,12 +44,16 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should patch a configuration connector and create mappings', async () => { const connector = await createConnector({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, }); @@ -107,7 +109,7 @@ export default ({ getService }: FtrProviderContext): void => { supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, }); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts index 96ffcf4bc3f5c..077bfc5861322 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts @@ -5,14 +5,11 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { getConfigurationRequest, @@ -22,22 +19,23 @@ import { createConfiguration, createConnector, getServiceNowConnector, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - const kibanaServer = getService('kibanaServer'); describe('post_configure', () => { const actionsRemover = new ActionsRemover(supertest); - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -45,12 +43,16 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should create a configuration with mapping', async () => { const connector = await createConnector({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, }); diff --git a/x-pack/test/case_api_integration/security_only/tests/trial/cases/push_case.ts b/x-pack/test/case_api_integration/security_only/tests/trial/cases/push_case.ts index 6294400281b92..69d403ea15301 100644 --- a/x-pack/test/case_api_integration/security_only/tests/trial/cases/push_case.ts +++ b/x-pack/test/case_api_integration/security_only/tests/trial/cases/push_case.ts @@ -5,6 +5,8 @@ * 2.0. */ +import http from 'http'; + import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; @@ -13,11 +15,8 @@ import { pushCase, deleteAllCaseItems, createCaseWithConnector, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { globalRead, noKibanaPrivileges, @@ -31,17 +30,17 @@ import { secOnlyDefaultSpaceAuth } from '../../../utils'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); - const kibanaServer = getService('kibanaServer'); const es = getService('es'); describe('push_case', () => { const actionsRemover = new ActionsRemover(supertest); + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - let servicenowSimulatorURL: string = '<could not determine kibana url>'; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -49,12 +48,16 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + const supertestWithoutAuth = getService('supertestWithoutAuth'); it('should push a case that the user has permissions for', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); @@ -69,7 +72,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should not push a case that the user does not have permissions for', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, createCaseReq: getPostCaseRequest({ owner: 'observabilityFixture' }), }); @@ -95,7 +98,7 @@ export default ({ getService }: FtrProviderContext): void => { } with role(s) ${user.roles.join()} - should NOT push a case`, async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); @@ -112,7 +115,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return a 404 when attempting to access a space', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, }); diff --git a/x-pack/test/case_api_integration/spaces_only/tests/trial/cases/push_case.ts b/x-pack/test/case_api_integration/spaces_only/tests/trial/cases/push_case.ts index 28b7fe6095507..bfb266e6f6c3a 100644 --- a/x-pack/test/case_api_integration/spaces_only/tests/trial/cases/push_case.ts +++ b/x-pack/test/case_api_integration/spaces_only/tests/trial/cases/push_case.ts @@ -6,7 +6,7 @@ */ /* eslint-disable @typescript-eslint/naming-convention */ - +import http from 'http'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; @@ -17,27 +17,24 @@ import { deleteAllCaseItems, createCaseWithConnector, getAuthWithSuperUser, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); - const kibanaServer = getService('kibanaServer'); const es = getService('es'); const authSpace1 = getAuthWithSuperUser(); describe('push_case', () => { const actionsRemover = new ActionsRemover(supertest); + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - let servicenowSimulatorURL: string = '<could not determine kibana url>'; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -45,10 +42,14 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should push a case in space1', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth: authSpace1, }); @@ -69,18 +70,13 @@ export default ({ getService }: FtrProviderContext): void => { external_title: 'INC01', }); - // external_url is of the form http://elastic:changeme@localhost:5620 which is different between various environments like Jekins - expect( - external_url.includes( - 'api/_actions-FTS-external-service-simulators/servicenow/nav_to.do?uri=incident.do?sys_id=123' - ) - ).to.equal(true); + expect(external_url.includes('nav_to.do?uri=incident.do?sys_id=123')).to.equal(true); }); it('should not push a case in a different space', async () => { const { postedCase, connector } = await createCaseWithConnector({ supertest, - servicenowSimulatorURL, + serviceNowSimulatorURL, actionsRemover, auth: authSpace1, }); diff --git a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_configure.ts b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_configure.ts index a142e6470ae93..4da44f08c6236 100644 --- a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_configure.ts +++ b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_configure.ts @@ -5,14 +5,10 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; - import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { getServiceNowConnector, @@ -23,6 +19,7 @@ import { removeServerGeneratedPropertiesFromSavedObject, getConfigurationOutput, getAuthWithSuperUser, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; import { nullUser } from '../../../../common/lib/mock'; @@ -31,28 +28,32 @@ import { nullUser } from '../../../../common/lib/mock'; export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const actionsRemover = new ActionsRemover(supertest); - const kibanaServer = getService('kibanaServer'); const authSpace1 = getAuthWithSuperUser(); describe('get_configure', () => { - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should return a configuration with a mapping from space1', async () => { const connector = await createConnector({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, auth: authSpace1, }); @@ -107,7 +108,7 @@ export default ({ getService }: FtrProviderContext): void => { supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, auth: authSpace1, }); diff --git a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index 0301fa3a930cb..7b6848d1f301e 100644 --- a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -109,6 +109,7 @@ export default ({ getService }: FtrProviderContext): void => { name: 'ServiceNow Connector', config: { apiUrl: 'http://some.non.existent.com', + isLegacy: false, }, isPreconfigured: false, isMissingSecrets: false, @@ -118,7 +119,10 @@ export default ({ getService }: FtrProviderContext): void => { id: sir.id, actionTypeId: '.servicenow-sir', name: 'ServiceNow Connector', - config: { apiUrl: 'http://some.non.existent.com' }, + config: { + apiUrl: 'http://some.non.existent.com', + isLegacy: false, + }, isPreconfigured: false, isMissingSecrets: false, referencedByCount: 0, diff --git a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/patch_configure.ts b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/patch_configure.ts index 14d0debe2ac17..ca362d13ae459 100644 --- a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/patch_configure.ts +++ b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/patch_configure.ts @@ -5,13 +5,10 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { getConfigurationRequest, @@ -24,6 +21,7 @@ import { createConnector, getAuthWithSuperUser, getActionsSpace, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; import { nullUser } from '../../../../common/lib/mock'; @@ -32,18 +30,18 @@ import { nullUser } from '../../../../common/lib/mock'; export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - const kibanaServer = getService('kibanaServer'); const authSpace1 = getAuthWithSuperUser(); const space = getActionsSpace(authSpace1.space); describe('patch_configure', () => { const actionsRemover = new ActionsRemover(supertest); - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -51,12 +49,16 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should patch a configuration connector and create mappings in space1', async () => { const connector = await createConnector({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, auth: authSpace1, }); @@ -126,7 +128,7 @@ export default ({ getService }: FtrProviderContext): void => { supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, auth: authSpace1, }); diff --git a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/post_configure.ts b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/post_configure.ts index 7c5035193d465..b815278db5bd8 100644 --- a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/post_configure.ts +++ b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/post_configure.ts @@ -5,14 +5,11 @@ * 2.0. */ +import http from 'http'; import expect from '@kbn/expect'; import { ConnectorTypes } from '../../../../../../plugins/cases/common/api'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; -import { - ExternalServiceSimulator, - getExternalServiceSimulatorPath, -} from '../../../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin'; import { getConfigurationRequest, @@ -24,6 +21,7 @@ import { getServiceNowConnector, getAuthWithSuperUser, getActionsSpace, + getServiceNowSimulationServer, } from '../../../../common/lib/utils'; import { nullUser } from '../../../../common/lib/mock'; @@ -31,18 +29,18 @@ import { nullUser } from '../../../../common/lib/mock'; export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - const kibanaServer = getService('kibanaServer'); const authSpace1 = getAuthWithSuperUser(); const space = getActionsSpace(authSpace1.space); describe('post_configure', () => { const actionsRemover = new ActionsRemover(supertest); - let servicenowSimulatorURL: string = '<could not determine kibana url>'; + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; - before(() => { - servicenowSimulatorURL = kibanaServer.resolveUrl( - getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) - ); + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; }); afterEach(async () => { @@ -50,12 +48,16 @@ export default ({ getService }: FtrProviderContext): void => { await actionsRemover.removeAll(); }); + after(async () => { + serviceNowServer.close(); + }); + it('should create a configuration with a mapping in space1', async () => { const connector = await createConnector({ supertest, req: { ...getServiceNowConnector(), - config: { apiUrl: servicenowSimulatorURL }, + config: { apiUrl: serviceNowSimulatorURL }, }, auth: authSpace1, }); diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/index.ts b/x-pack/test/detection_engine_api_integration/basic/tests/index.ts index 802b1e78930e8..5fa4540bbe854 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default ({ loadTestFile }: FtrProviderContext): void => { - describe('detection engine api security and spaces enabled', function () { + describe('detection engine api basic license', function () { this.tags('ciGroup1'); loadTestFile(require.resolve('./add_prepackaged_rules')); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts index b4bd74172920b..1b88c4fe21b49 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts @@ -33,6 +33,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./get_prepackaged_rules_status')); loadTestFile(require.resolve('./import_rules')); loadTestFile(require.resolve('./read_rules')); + loadTestFile(require.resolve('./resolve_read_rules')); loadTestFile(require.resolve('./update_rules')); loadTestFile(require.resolve('./update_rules_bulk')); loadTestFile(require.resolve('./patch_rules_bulk')); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.ts new file mode 100644 index 0000000000000..6013398d4695d --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.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 expect from '@kbn/expect'; + +import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { createSignalsIndex, deleteAllAlerts, deleteSignalsIndex } from '../../utils'; + +const spaceId = '714-space'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + const esArchiver = getService('esArchiver'); + + describe('resolve_read_rules', () => { + describe('reading rules', () => { + beforeEach(async () => { + await createSignalsIndex(supertest); + await esArchiver.load( + 'x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14' + ); + }); + + afterEach(async () => { + await deleteSignalsIndex(supertest); + await deleteAllAlerts(supertest); + await esArchiver.unload( + 'x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14' + ); + }); + + it('should create a "migrated" rule where querying for the new SO _id will resolve the new object and not return the outcome field when outcome === exactMatch', async () => { + // link to the new URL with migrated SO id 74f3e6d7-b7bb-477d-ac28-92ee22728e6e + const URL = `/s/${spaceId}${DETECTION_ENGINE_RULES_URL}?id=90e3ca0e-71f7-513a-b60a-ac678efd8887`; + const readRulesAliasMatchRes = await supertest.get(URL).set('kbn-xsrf', 'true').send(); + expect(readRulesAliasMatchRes.body.outcome).to.eql('aliasMatch'); + + // now that we have the migrated alias_target_id, let's attempt an 'exactMatch' query + // the result of which should have the outcome as undefined when querying the read rules api. + const exactMatchURL = `/s/${spaceId}${DETECTION_ENGINE_RULES_URL}?id=${readRulesAliasMatchRes.body.alias_target_id}`; + const readRulesExactMatchRes = await supertest + .get(exactMatchURL) + .set('kbn-xsrf', 'true') + .send(); + expect(readRulesExactMatchRes.body.outcome).to.eql(undefined); + }); + + it('should create a rule and a "conflicting rule" where the SO _id matches the sourceId (see legacy-url-alias SO) of a migrated rule', async () => { + // mimic a rule SO that was inserted accidentally + // we have to insert this outside of esArchiver otherwise kibana will migrate this + // and we won't have a conflict + await es.index({ + id: 'alert:90e3ca0e-71f7-513a-b60a-ac678efd8887', + index: '.kibana', + refresh: true, + body: { + alert: { + name: 'test 7.14', + tags: [ + '__internal_rule_id:82747bb8-bae0-4b59-8119-7f65ac564e14', + '__internal_immutable:false', + ], + alertTypeId: 'siem.signals', + consumer: 'siem', + params: { + author: [], + description: 'test', + ruleId: '82747bb8-bae0-4b59-8119-7f65ac564e14', + falsePositives: [], + from: 'now-3615s', + immutable: false, + license: '', + outputIndex: '.siem-signals-devin-hurley-714-space', + meta: { + from: '1h', + kibana_siem_app_url: 'http://0.0.0.0:5601/s/714-space/app/security', + }, + maxSignals: 100, + riskScore: 21, + riskScoreMapping: [], + severity: 'low', + severityMapping: [], + threat: [], + to: 'now', + references: [], + version: 1, + exceptionsList: [], + type: 'query', + language: 'kuery', + index: [ + 'apm-*-transaction*', + 'traces-apm*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + query: '*:*', + filters: [], + }, + schedule: { + interval: '15s', + }, + enabled: true, + actions: [], + throttle: null, + notifyWhen: 'onActiveAlert', + apiKeyOwner: 'elastic', + apiKey: + 'HvwrIJ8NBshJav9vf3BSEEa2P7fXLTpmEKAx2bSyBF51N2cadFkltWLRRcFnj65RXsPzvRm3VKzAde4b1iGzsjxY/IVmfGGyiO0rk6vZVJVLeMSD+CAiflnwweypoKM8WgwXJnI0Oa/SWqKMtrDiFxCcZCwIuAhS0sjenaiEuedbAuStZv513zz/clpqRKFXBydJXKyjJUQLTA==', + createdBy: 'elastic', + updatedBy: 'elastic', + createdAt: '2021-10-05T19:52:25.865Z', + updatedAt: '2021-10-05T19:52:25.865Z', + muteAll: false, + mutedInstanceIds: [], + executionStatus: { + status: 'ok', + lastExecutionDate: '2021-10-05T19:52:51.260Z', + error: null, + }, + meta: { + versionApiKeyLastmodified: '7.14.2', + }, + scheduledTaskId: 'c4005e90-2615-11ec-811e-db7211397897', + legacyId: 'c364e1e0-2615-11ec-811e-db7211397897', + }, + type: 'alert', + references: [], + namespaces: [spaceId], + originId: 'c364e1e0-2615-11ec-811e-db7211397897', + migrationVersion: { + alert: '8.0.0', + }, + coreMigrationVersion: '8.0.0', + updated_at: '2021-10-05T19:52:56.014Z', + }, + }); + + // Now that we have a rule id and a legacy-url-alias with the same id, we should have a conflict + const conflictURL = `/s/${spaceId}${DETECTION_ENGINE_RULES_URL}?id=90e3ca0e-71f7-513a-b60a-ac678efd8887`; + const readRulesConflictRes = await supertest + .get(conflictURL) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + expect(readRulesConflictRes.body.outcome).to.eql('conflict'); + }); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/utils.ts b/x-pack/test/detection_engine_api_integration/utils.ts index ac27f06a149d9..eeae21c3b7bad 100644 --- a/x-pack/test/detection_engine_api_integration/utils.ts +++ b/x-pack/test/detection_engine_api_integration/utils.ts @@ -369,17 +369,31 @@ export const getSimpleRuleOutput = (ruleId = 'rule-1', enabled = false): Partial version: 1, }); +export const resolveSimpleRuleOutput = ( + ruleId = 'rule-1', + enabled = false +): Partial<RulesSchema> => ({ outcome: 'exactMatch', ...getSimpleRuleOutput(ruleId, enabled) }); + /** * This is the typical output of a simple rule that Kibana will output with all the defaults except * for all the server generated properties such as created_by. Useful for testing end to end tests. */ export const getSimpleRuleOutputWithoutRuleId = (ruleId = 'rule-1'): Partial<RulesSchema> => { const rule = getSimpleRuleOutput(ruleId); - // eslint-disable-next-line @typescript-eslint/naming-convention - const { rule_id, ...ruleWithoutRuleId } = rule; + const { rule_id: rId, ...ruleWithoutRuleId } = rule; return ruleWithoutRuleId; }; +/** + * This is the typical output of a simple rule that Kibana will output with all the defaults except + * for all the server generated properties such as created_by. Useful for testing end to end tests. + */ +export const resolveSimpleRuleOutputWithoutRuleId = (ruleId = 'rule-1'): Partial<RulesSchema> => { + const rule = getSimpleRuleOutput(ruleId); + const { rule_id: rId, ...ruleWithoutRuleId } = rule; + return { outcome: 'exactMatch', ...ruleWithoutRuleId }; +}; + export const getSimpleMlRuleOutput = (ruleId = 'rule-1'): Partial<RulesSchema> => { const rule = getSimpleRuleOutput(ruleId); const { query, language, index, ...rest } = rule; @@ -399,12 +413,17 @@ export const getSimpleMlRuleOutput = (ruleId = 'rule-1'): Partial<RulesSchema> = * @param supertest The supertest agent. */ export const deleteAllAlerts = async ( - supertest: SuperTest.SuperTest<SuperTest.Test> + supertest: SuperTest.SuperTest<SuperTest.Test>, + space?: string ): Promise<void> => { await countDownTest( async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_RULES_URL}/_find?per_page=9999`) + .get( + space + ? `/s/${space}${DETECTION_ENGINE_RULES_URL}/_find?per_page=9999` + : `${DETECTION_ENGINE_RULES_URL}/_find?per_page=9999` + ) .set('kbn-xsrf', 'true') .send(); @@ -413,7 +432,11 @@ export const deleteAllAlerts = async ( })); await supertest - .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) + .post( + space + ? `/s/${space}${DETECTION_ENGINE_RULES_URL}/_bulk_delete` + : `${DETECTION_ENGINE_RULES_URL}/_bulk_delete` + ) .send(ids) .set('kbn-xsrf', 'true'); diff --git a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects/mappings.json b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects/mappings.json index a083c8f7e3bcf..be99452707814 100644 --- a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects/mappings.json +++ b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects/mappings.json @@ -189,27 +189,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects_different_key/mappings.json b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects_different_key/mappings.json index 22b79eb9bbd8e..dfcf3155b67ca 100644 --- a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects_different_key/mappings.json +++ b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/encrypted_saved_objects_different_key/mappings.json @@ -216,27 +216,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/key_rotation/mappings.json b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/key_rotation/mappings.json index 74083cbfa949a..72f66db35cec6 100644 --- a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/key_rotation/mappings.json +++ b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/es_archiver/key_rotation/mappings.json @@ -214,27 +214,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/fleet_api_integration/apis/agents/list.ts b/x-pack/test/fleet_api_integration/apis/agents/list.ts index a11f4d49fe0f1..3795734f60fe0 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/list.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/list.ts @@ -8,66 +8,15 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { testUsers } from '../test_users'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const supertestWithoutAuth = getService('supertestWithoutAuth'); const supertest = getService('supertest'); - const security = getService('security'); - const users: { [rollName: string]: { username: string; password: string; permissions?: any } } = { - kibana_basic_user: { - permissions: { - feature: { - dashboards: ['read'], - }, - spaces: ['*'], - }, - username: 'kibana_basic_user', - password: 'changeme', - }, - fleet_user: { - permissions: { - feature: { - fleet: ['read'], - }, - spaces: ['*'], - }, - username: 'fleet_user', - password: 'changeme', - }, - fleet_admin: { - permissions: { - feature: { - fleet: ['all'], - }, - spaces: ['*'], - }, - username: 'fleet_admin', - password: 'changeme', - }, - }; describe('fleet_list_agent', () => { before(async () => { - for (const roleName in users) { - if (users.hasOwnProperty(roleName)) { - const user = users[roleName]; - - if (user.permissions) { - await security.role.create(roleName, { - kibana: [user.permissions], - }); - } - - // Import a repository first - await security.user.create(user.username, { - password: user.password, - roles: [roleName], - full_name: user.username, - }); - } - } - await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/fleet/agents'); }); after(async () => { @@ -77,13 +26,13 @@ export default function ({ getService }: FtrProviderContext) { it('should return a 403 if a user without the superuser role try to access the APU', async () => { await supertestWithoutAuth .get(`/api/fleet/agents`) - .auth(users.fleet_admin.username, users.fleet_admin.password) + .auth(testUsers.fleet_all.username, testUsers.fleet_all.password) .expect(403); }); it('should not return the list of agents when requesting as a user without fleet permissions', async () => { await supertestWithoutAuth .get(`/api/fleet/agents`) - .auth(users.kibana_basic_user.username, users.kibana_basic_user.password) + .auth(testUsers.fleet_no_access.username, testUsers.fleet_no_access.password) .expect(403); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts b/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts index bb75629e222a5..3b3ccb03e56f3 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts @@ -14,10 +14,12 @@ import { IBulkInstallPackageHTTPError, } from '../../../../plugins/fleet/common'; import { setupFleetAndAgents } from '../agents/services'; +import { testUsers } from '../test_users'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const deletePackage = async (pkgkey: string) => { await supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); @@ -44,6 +46,13 @@ export default function (providerContext: FtrProviderContext) { it('should return 400 if no packages are requested for upgrade', async function () { await supertest.post(`/api/fleet/epm/packages/_bulk`).set('kbn-xsrf', 'xxxx').expect(400); }); + it('should return 403 if read only user requests upgrade', async function () { + await supertestWithoutAuth + .post(`/api/fleet/epm/packages/_bulk`) + .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) + .set('kbn-xsrf', 'xxxx') + .expect(403); + }); it('should return 200 and an array for upgrading a package', async function () { const { body }: { body: BulkInstallPackagesResponse } = await supertest .post(`/api/fleet/epm/packages/_bulk`) diff --git a/x-pack/test/fleet_api_integration/apis/epm/delete.ts b/x-pack/test/fleet_api_integration/apis/epm/delete.ts index 40650c4c176f7..9980d85ac171e 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/delete.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/delete.ts @@ -8,10 +8,12 @@ import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; import { setupFleetAndAgents } from '../agents/services'; +import { testUsers } from '../test_users'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const requiredPackage = 'elastic_agent-0.0.7'; const installPackage = async (pkgkey: string) => { @@ -52,5 +54,13 @@ export default function (providerContext: FtrProviderContext) { .send({ force: true }) .expect(200); }); + + it('should return 403 for read-only users', async () => { + await supertestWithoutAuth + .delete(`/api/fleet/epm/packages/${requiredPackage}`) + .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) + .set('kbn-xsrf', 'xxxx') + .expect(403); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/get.ts b/x-pack/test/fleet_api_integration/apis/epm/get.ts index 014fe0808d255..13533a9a82af0 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/get.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/get.ts @@ -11,11 +11,13 @@ import path from 'path'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; import { setupFleetAndAgents } from '../agents/services'; +import { testUsers } from '../test_users'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const testPkgKey = 'apache-0.1.4'; @@ -91,5 +93,12 @@ export default function (providerContext: FtrProviderContext) { it('returns a 400 for a package key without a proper semver version', async function () { await supertest.get('/api/fleet/epm/packages/endpoint-0.1.0.1.2.3').expect(400); }); + + it('allows user with only read permission to access', async () => { + await supertestWithoutAuth + .get(`/api/fleet/epm/packages/${testPkgKey}`) + .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) + .expect(200); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts index 23feacbcee374..86928874f8a34 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts @@ -12,10 +12,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; import { setupFleetAndAgents } from '../agents/services'; +import { testUsers } from '../test_users'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const dockerServers = getService('dockerServers'); const testPkgArchiveTgz = path.join( @@ -190,5 +192,16 @@ export default function (providerContext: FtrProviderContext) { '{"statusCode":400,"error":"Bad Request","message":"Name thisIsATypo and version 0.1.4 do not match top-level directory apache-0.1.4"}' ); }); + + it('should not allow users without all access', async () => { + const buf = fs.readFileSync(testPkgArchiveTgz); + await supertestWithoutAuth + .post(`/api/fleet/epm/packages`) + .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) + .set('kbn-xsrf', 'xxxx') + .type('application/gzip') + .send(buf) + .expect(403); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/list.ts b/x-pack/test/fleet_api_integration/apis/epm/list.ts index 931e494798220..56f3e6ca1f2fa 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/list.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/list.ts @@ -9,10 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; import { setupFleetAndAgents } from '../agents/services'; +import { testUsers } from '../test_users'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const esArchiver = getService('esArchiver'); // use function () {} and not () => {} here @@ -54,6 +56,13 @@ export default function (providerContext: FtrProviderContext) { expect(listResponse.response).to.eql(['endpoint']); }); + + it('allows user with only read permission to access', async () => { + await supertestWithoutAuth + .get('/api/fleet/epm/packages') + .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) + .expect(200); + }); }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/index.js b/x-pack/test/fleet_api_integration/apis/index.js index 387433b787728..fd5ac05247fd2 100644 --- a/x-pack/test/fleet_api_integration/apis/index.js +++ b/x-pack/test/fleet_api_integration/apis/index.js @@ -5,10 +5,16 @@ * 2.0. */ -export default function ({ loadTestFile }) { +import { setupTestUsers } from './test_users'; + +export default function ({ loadTestFile, getService }) { describe('Fleet Endpoints', function () { + before(async () => { + await setupTestUsers(getService('security')); + }); + // EPM - loadTestFile(require.resolve('./epm/index')); + loadTestFile(require.resolve('./epm')); // Fleet setup loadTestFile(require.resolve('./fleet_setup')); diff --git a/x-pack/test/fleet_api_integration/apis/test_users.ts b/x-pack/test/fleet_api_integration/apis/test_users.ts new file mode 100644 index 0000000000000..a1df6d3a31b71 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/test_users.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 type { SecurityService } from '../../../../test/common/services/security/security'; + +export const testUsers: { + [rollName: string]: { username: string; password: string; permissions?: any }; +} = { + fleet_no_access: { + permissions: { + feature: { + dashboards: ['read'], + }, + spaces: ['*'], + }, + username: 'fleet_no_access', + password: 'changeme', + }, + fleet_read_only: { + permissions: { + feature: { + fleet: ['read'], + }, + spaces: ['*'], + }, + username: 'fleet_read_only', + password: 'changeme', + }, + fleet_all: { + permissions: { + feature: { + fleet: ['all'], + }, + spaces: ['*'], + }, + username: 'fleet_all', + password: 'changeme', + }, +}; + +export const setupTestUsers = async (security: SecurityService) => { + for (const roleName in testUsers) { + if (testUsers.hasOwnProperty(roleName)) { + const user = testUsers[roleName]; + + if (user.permissions) { + await security.role.create(roleName, { + kibana: [user.permissions], + }); + } + + await security.user.create(user.username, { + password: user.password, + roles: [roleName], + full_name: user.username, + }); + } + } +}; diff --git a/x-pack/test/fleet_api_integration/config.ts b/x-pack/test/fleet_api_integration/config.ts index d1c6c3c3f6b1e..d2b61a3f5c321 100644 --- a/x-pack/test/fleet_api_integration/config.ts +++ b/x-pack/test/fleet_api_integration/config.ts @@ -15,7 +15,7 @@ import { defineDockerServersConfig } from '@kbn/test'; // example: https://beats-ci.elastic.co/blue/organizations/jenkins/Ingest-manager%2Fpackage-storage/detail/snapshot/74/pipeline/257#step-302-log-1. // It should be updated any time there is a new Docker image published for the Snapshot Distribution of the Package Registry. export const dockerImage = - 'docker.elastic.co/package-registry/distribution@sha256:35cedaaa6adac547947321fa0c3b60a63eba153ba09524b9c1a21f1247a09bd2'; + 'docker.elastic.co/package-registry/distribution@sha256:42dbdbb7fbc7ea61d0c38c0df6dad977ca2ad9cf01e247543054377aef33d377'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts')); diff --git a/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts b/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts index f2b872bccbaa7..71f100b49068f 100644 --- a/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts +++ b/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts @@ -52,7 +52,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { basePath: '/s/custom_space', }); - const exists = await find.existsByCssSelector('monitoring-main'); + const exists = await find.existsByCssSelector('[data-test-subj="monitoringAppContainer"]'); expect(exists).to.be(true); }); }); diff --git a/x-pack/test/functional/apps/monitoring/index.js b/x-pack/test/functional/apps/monitoring/index.js index 213007c7b71df..6a5b6ea813171 100644 --- a/x-pack/test/functional/apps/monitoring/index.js +++ b/x-pack/test/functional/apps/monitoring/index.js @@ -34,10 +34,6 @@ export default function ({ loadTestFile }) { loadTestFile(require.resolve('./kibana/instance')); loadTestFile(require.resolve('./kibana/instance_mb')); - // loadTestFile(require.resolve('./logstash/overview')); - // loadTestFile(require.resolve('./logstash/nodes')); - // loadTestFile(require.resolve('./logstash/node')); - loadTestFile(require.resolve('./logstash/pipelines')); loadTestFile(require.resolve('./logstash/pipelines_mb')); diff --git a/x-pack/test/functional/apps/reporting/README.md b/x-pack/test/functional/apps/reporting/README.md new file mode 100644 index 0000000000000..ec9bba8b88341 --- /dev/null +++ b/x-pack/test/functional/apps/reporting/README.md @@ -0,0 +1,18 @@ +## Reporting functional tests + +Functional tests on report generation are under the applications that use reporting. + +**PDF/PNG Report testing:** + - `x-pack/test/functional/apps/canvas/reports.ts` + - `x-pack/test/functional/apps/dashboard/reporting/screenshots.ts` + - `x-pack/test/functional/apps/lens/lens_reporting.ts` + - `x-pack/test/functional/apps/visualize/reporting.ts` + +**CSV Report testing:** + - `x-pack/test/functional/apps/dashboard/reporting/download_csv.ts` + - `x-pack/test/functional/apps/discover/reporting.ts` + +Reporting Management app tests are in `functional/apps/reporting_management`. + +**Manage reports testing:** + - `x-pack/test/functional/apps/reporting_management` diff --git a/x-pack/test/functional/apps/reporting/reporting.ts b/x-pack/test/functional/apps/reporting/reporting.ts deleted file mode 100644 index 0d8034f046e02..0000000000000 --- a/x-pack/test/functional/apps/reporting/reporting.ts +++ /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 expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const pageObjects = getPageObjects(['dashboard', 'common', 'reporting']); - const es = getService('es'); - const kibanaServer = getService('kibanaServer'); - - const retry = getService('retry'); - - describe('Reporting', function () { - this.tags(['smoke', 'ciGroup2']); - before(async () => { - await kibanaServer.importExport.load( - 'x-pack/test/functional/fixtures/kbn_archiver/packaging' - ); - }); - - after(async () => { - await kibanaServer.importExport.unload( - 'x-pack/test/functional/fixtures/kbn_archiver/packaging' - ); - await es.deleteByQuery({ - index: '.reporting-*', - refresh: true, - body: { query: { match_all: {} } }, - }); - }); - - it('downloaded PDF has OK status', async function () { - this.timeout(180000); - - await pageObjects.common.navigateToApp('dashboards'); - await retry.waitFor('dashboard landing page', async () => { - return await pageObjects.dashboard.onDashboardLandingPage(); - }); - await pageObjects.dashboard.loadSavedDashboard('dashboard'); - await pageObjects.reporting.openPdfReportingPanel(); - await pageObjects.reporting.clickGenerateReportButton(); - - const url = await pageObjects.reporting.getReportURL(60000); - const res = await pageObjects.reporting.getResponse(url); - - expect(res.status).to.equal(200); - expect(res.get('content-type')).to.equal('application/pdf'); - }); - }); -} diff --git a/x-pack/test/functional/apps/transform/creation_runtime_mappings.ts b/x-pack/test/functional/apps/transform/creation_runtime_mappings.ts index 5fe9d02c58dc7..e244c907a76d6 100644 --- a/x-pack/test/functional/apps/transform/creation_runtime_mappings.ts +++ b/x-pack/test/functional/apps/transform/creation_runtime_mappings.ts @@ -33,7 +33,9 @@ export default function ({ getService }: FtrProviderContext) { script: "emit(doc['responsetime'].value * 2.0)", }, }; - describe('creation with runtime mappings', function () { + + // FLAKY https://github.com/elastic/kibana/issues/113890 + describe.skip('creation with runtime mappings', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await transform.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index 04622c5f21fac..2abd91fd0433a 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -56,7 +56,6 @@ export default async function ({ readConfigFile }) { resolve(__dirname, './apps/transform'), resolve(__dirname, './apps/reporting_management'), resolve(__dirname, './apps/management'), - resolve(__dirname, './apps/reporting'), resolve(__dirname, './apps/lens'), // smokescreen tests cause flakiness in other tests // This license_management file must be last because it is destructive. diff --git a/x-pack/test/functional/es_archives/action_task_params/mappings.json b/x-pack/test/functional/es_archives/action_task_params/mappings.json index 2bb6be179d890..d28c1504d3eed 100644 --- a/x-pack/test/functional/es_archives/action_task_params/mappings.json +++ b/x-pack/test/functional/es_archives/action_task_params/mappings.json @@ -206,27 +206,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/actions/mappings.json b/x-pack/test/functional/es_archives/actions/mappings.json index eeb9d09d3b0a2..a0da38c85f724 100644 --- a/x-pack/test/functional/es_archives/actions/mappings.json +++ b/x-pack/test/functional/es_archives/actions/mappings.json @@ -202,27 +202,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/alerts_legacy/mappings.json b/x-pack/test/functional/es_archives/alerts_legacy/mappings.json index 69edf30c1ffd0..6e40f811e1af4 100644 --- a/x-pack/test/functional/es_archives/alerts_legacy/mappings.json +++ b/x-pack/test/functional/es_archives/alerts_legacy/mappings.json @@ -198,27 +198,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/canvas/reports/mappings.json b/x-pack/test/functional/es_archives/canvas/reports/mappings.json index 047a52aaa1f98..d6c3f1b26a430 100644 --- a/x-pack/test/functional/es_archives/canvas/reports/mappings.json +++ b/x-pack/test/functional/es_archives/canvas/reports/mappings.json @@ -229,27 +229,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/cases/migrations/7.10.0/mappings.json b/x-pack/test/functional/es_archives/cases/migrations/7.10.0/mappings.json index c7e1a180e6c54..b1b6c468c3945 100644 --- a/x-pack/test/functional/es_archives/cases/migrations/7.10.0/mappings.json +++ b/x-pack/test/functional/es_archives/cases/migrations/7.10.0/mappings.json @@ -199,27 +199,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/cases/migrations/7.11.1/mappings.json b/x-pack/test/functional/es_archives/cases/migrations/7.11.1/mappings.json index bc719ab40aebd..94648d407a89b 100644 --- a/x-pack/test/functional/es_archives/cases/migrations/7.11.1/mappings.json +++ b/x-pack/test/functional/es_archives/cases/migrations/7.11.1/mappings.json @@ -254,27 +254,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, @@ -2720,4 +2716,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/cases/migrations/7.13.2/mappings.json b/x-pack/test/functional/es_archives/cases/migrations/7.13.2/mappings.json index 88f3e5d78cb16..6f4a2df3a7543 100644 --- a/x-pack/test/functional/es_archives/cases/migrations/7.13.2/mappings.json +++ b/x-pack/test/functional/es_archives/cases/migrations/7.13.2/mappings.json @@ -260,27 +260,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, @@ -2864,4 +2860,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/cases/migrations/7.13_user_actions/mappings.json b/x-pack/test/functional/es_archives/cases/migrations/7.13_user_actions/mappings.json index c6b71a2613859..7026e50cdb658 100644 --- a/x-pack/test/functional/es_archives/cases/migrations/7.13_user_actions/mappings.json +++ b/x-pack/test/functional/es_archives/cases/migrations/7.13_user_actions/mappings.json @@ -261,27 +261,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, @@ -2951,4 +2947,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/cases/migrations/7.16.0_space/mappings.json b/x-pack/test/functional/es_archives/cases/migrations/7.16.0_space/mappings.json index 51fe50218b1f5..d7422d4236598 100644 --- a/x-pack/test/functional/es_archives/cases/migrations/7.16.0_space/mappings.json +++ b/x-pack/test/functional/es_archives/cases/migrations/7.16.0_space/mappings.json @@ -275,27 +275,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/data/search_sessions/mappings.json b/x-pack/test/functional/es_archives/data/search_sessions/mappings.json index a3eab7787c3eb..07c2c88b9f38f 100644 --- a/x-pack/test/functional/es_archives/data/search_sessions/mappings.json +++ b/x-pack/test/functional/es_archives/data/search_sessions/mappings.json @@ -169,27 +169,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/agent_only/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/agent_only/mappings.json index 4dcb8f905b197..dd65c3977e1b7 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/agent_only/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/agent_only/mappings.json @@ -198,27 +198,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_different_states/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_different_states/mappings.json index d6d91281151aa..eecc8ee5d8870 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_different_states/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_different_states/mappings.json @@ -199,27 +199,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_installed/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_installed/mappings.json index d6d91281151aa..eecc8ee5d8870 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_installed/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_installed/mappings.json @@ -199,27 +199,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_uninstalled/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_uninstalled/mappings.json index d6d91281151aa..eecc8ee5d8870 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_uninstalled/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/cloned_endpoint_uninstalled/mappings.json @@ -199,27 +199,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_disabled/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_disabled/mappings.json index 4dcb8f905b197..dd65c3977e1b7 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_disabled/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_disabled/mappings.json @@ -198,27 +198,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_enabled/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_enabled/mappings.json index 4dcb8f905b197..dd65c3977e1b7 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_enabled/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_malware_enabled/mappings.json @@ -198,27 +198,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_uninstalled/mappings.json b/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_uninstalled/mappings.json index 4dcb8f905b197..dd65c3977e1b7 100644 --- a/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_uninstalled/mappings.json +++ b/x-pack/test/functional/es_archives/endpoint/telemetry/endpoint_uninstalled/mappings.json @@ -198,27 +198,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index 8e4c7a912b75a..24b4a66624305 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -189,27 +189,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/kibana_scripted_fields_on_logstash/mappings.json b/x-pack/test/functional/es_archives/kibana_scripted_fields_on_logstash/mappings.json index 7479c525f6a07..e0dd6d90eacb4 100644 --- a/x-pack/test/functional/es_archives/kibana_scripted_fields_on_logstash/mappings.json +++ b/x-pack/test/functional/es_archives/kibana_scripted_fields_on_logstash/mappings.json @@ -181,27 +181,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/lists/mappings.json b/x-pack/test/functional/es_archives/lists/mappings.json index 134ed28bac2e7..e687285f91b29 100644 --- a/x-pack/test/functional/es_archives/lists/mappings.json +++ b/x-pack/test/functional/es_archives/lists/mappings.json @@ -196,27 +196,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json index 5bffb9540e983..e67abaf2032c7 100644 --- a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json @@ -193,27 +193,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/reporting/ecommerce_kibana_spaces/mappings.json b/x-pack/test/functional/es_archives/reporting/ecommerce_kibana_spaces/mappings.json index 254184cbef584..0fe9a18ce2201 100644 --- a/x-pack/test/functional/es_archives/reporting/ecommerce_kibana_spaces/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/ecommerce_kibana_spaces/mappings.json @@ -214,27 +214,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/reporting/hugedata/mappings.json b/x-pack/test/functional/es_archives/reporting/hugedata/mappings.json index 1fdde9d9d208b..d1cb75c1f5150 100644 --- a/x-pack/test/functional/es_archives/reporting/hugedata/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/hugedata/mappings.json @@ -170,27 +170,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/reporting/multi_index_kibana/mappings.json b/x-pack/test/functional/es_archives/reporting/multi_index_kibana/mappings.json index f950877aea332..69c6cbc3b46b5 100644 --- a/x-pack/test/functional/es_archives/reporting/multi_index_kibana/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/multi_index_kibana/mappings.json @@ -172,27 +172,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, @@ -2028,4 +2024,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/security_solution/migrations/mappings.json b/x-pack/test/functional/es_archives/security_solution/migrations/mappings.json index 5a602322b3017..8728ec4ad74a1 100644 --- a/x-pack/test/functional/es_archives/security_solution/migrations/mappings.json +++ b/x-pack/test/functional/es_archives/security_solution/migrations/mappings.json @@ -272,27 +272,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14/data.json b/x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14/data.json new file mode 100644 index 0000000000000..498367c913dc0 --- /dev/null +++ b/x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14/data.json @@ -0,0 +1,101 @@ +{ + "type" : "doc", + "value": { + "index" : ".kibana_1", + "id" : "space:714-space", + "source" : { + "space" : { + "name" : "714-space", + "initials" : "t", + "color" : "#B9A888", + "disabledFeatures" : [ ], + "imageUrl" : "" + }, + "type" : "space", + "references" : [ ], + "migrationVersion" : { + "space" : "6.6.0" + }, + "updated_at" : "2021-10-11T14:49:07.012Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "714-space:alert:90e3ca0e-71f7-513a-b60a-ac678efd8887", + "index": ".kibana_1", + "source": { + "alert": { + "actions": [ + ], + "alertTypeId" : "siem.signals", + "consumer" : "siem", + "apiKey": "QIUT8u0/kbOakEHSj50jDpVR90MrqOxanEscboYOoa8PxQvcA5jfHash+fqH3b+KNjJ1LpnBcisGuPkufY9j1e32gKzwGZV5Bfys87imHvygJvIM8uKiFF8bQ8Y4NTaxOJO9fAmZPrFy07ZcQMCAQz+DUTgBFqs=", + "apiKeyOwner": "elastic", + "createdAt": "2020-06-17T15:35:38.497Z", + "createdBy": "elastic", + "enabled": true, + "muteAll": false, + "mutedInstanceIds": [ + ], + "name": "always-firing-alert", + "params":{ + "author": [], + "description": "test", + "ruleId": "82747bb8-bae0-4b59-8119-7f65ac564e14", + "falsePositives": [], + "from": "now-3615s", + "immutable": false, + "license": "", + "outputIndex": ".siem-signals-devin-hurley-714-space", + "meta": { + "from": "1h", + "kibana_siem_app_url": "http://0.0.0.0:5601/s/714-space/app/security" + }, + "maxSignals": 100, + "riskScore": 21, + "riskScoreMapping": [], + "severity": "low", + "severityMapping": [], + "threat": [], + "to": "now", + "references": [], + "version": 1, + "exceptionsList": [], + "type": "query", + "language": "kuery", + "index": [ + "apm-*-transaction*", + "traces-apm*", + "auditbeat-*", + "endgame-*", + "filebeat-*", + "logs-*", + "packetbeat-*", + "winlogbeat-*" + ], + "query": "*:*", + "filters": [] + }, + "schedule": { + "interval": "1m" + }, + "scheduledTaskId": "329798f0-b0b0-11ea-9510-fdf248d5f2a4", + "tags": [ + ], + "throttle": null, + "updatedBy": "elastic" + }, + "migrationVersion": { + "alert": "7.8.0" + }, + "references": [ + ], + "namespace": "714-space", + "type": "alert", + "updated_at": "2020-06-17T15:35:39.839Z" + } + } +} diff --git a/x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14/mappings.json b/x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14/mappings.json new file mode 100644 index 0000000000000..069f70badce4e --- /dev/null +++ b/x-pack/test/functional/es_archives/security_solution/resolve_read_rules/7_14/mappings.json @@ -0,0 +1,397 @@ +{ + "type": "index", + "value": { + "aliases": { + ".kibana": {} + }, + "index": ".kibana_1", + "mappings": { + "_meta": { + "migrationMappingPropertyHashes": { + "action": "6e96ac5e648f57523879661ea72525b7", + "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", + "alert": "7b44fba6773e37c806ce290ea9b7024e", + "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", + "apm-telemetry": "3525d7c22c42bc80f5e6e9cb3f2b26a2", + "application_usage_totals": "c897e4310c5f24b07caaff3db53ae2c1", + "application_usage_transactional": "965839e75f809fefe04f92dc4d99722a", + "canvas-element": "7390014e1091044523666d97247392fc", + "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", + "cases": "32aa96a6d3855ddda53010ae2048ac22", + "cases-comments": "c2061fb929f585df57425102fa928b4b", + "cases-configure": "42711cbb311976c0687853f4c1354572", + "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", + "config": "ae24d22d5986d04124cc6568f771066f", + "dashboard": "d00f614b29a80360e1190193fd333bab", + "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", + "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", + "index-pattern": "66eccb05066c5a89924f48a9e9736499", + "infrastructure-ui-source": "ddc0ecb18383f6b26101a2fadb2dab0c", + "inventory-view": "88fc7e12fd1b45b6f0787323ce4f18d2", + "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", + "lens": "d33c68a69ff1e78c9888dedd2164ac22", + "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", + "map": "23d7aa4a720d4938ccde3983f87bd58d", + "maps-telemetry": "bfd39d88aadadb4be597ea984d433dbe", + "metrics-explorer-view": "428e319af3e822c80a84cf87123ca35c", + "migrationVersion": "4a1746014a75ade3a714e1db5763276f", + "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", + "namespace": "2f4316de49999235636386fe51dc06c1", + "namespaces": "2f4316de49999235636386fe51dc06c1", + "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", + "references": "7997cf5a56cc02bdc9c93361bde732b0", + "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", + "search": "181661168bbadd1eff5902361e2a0d5c", + "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", + "telemetry": "36a616f7026dfa617d6655df850fe16d", + "todo": "082a2cc96a590268344d5cd74c159ac4", + "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", + "type": "2f4316de49999235636386fe51dc06c1", + "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", + "updated_at": "00da57df13e94e9d98437d13ace4bfe0", + "upgrade-assistant-reindex-operation": "296a89039fc4260292be36b1b005d8f2", + "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", + "uptime-dynamic-settings": "fcdb453a30092f022f2642db29523d80", + "url": "b675c3be8d76ecf029294d51dc7ec65d", + "visualization": "52d7a13ad68a150c4525b292d23e12cc" + } + }, + "dynamic": "strict", + "properties": { + "action": { + "properties": { + "actionTypeId": { + "type": "keyword" + }, + "config": { + "enabled": false, + "type": "object" + }, + "name": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + }, + "secrets": { + "type": "binary" + } + } + }, + "action_task_params": { + "properties": { + "actionId": { + "type": "keyword" + }, + "apiKey": { + "type": "binary" + }, + "params": { + "enabled": false, + "type": "object" + } + } + }, + "alert": { + "properties": { + "actions": { + "properties": { + "actionRef": { + "type": "keyword" + }, + "actionTypeId": { + "type": "keyword" + }, + "group": { + "type": "keyword" + }, + "params": { + "enabled": false, + "type": "object" + } + }, + "type": "nested" + }, + "alertTypeId": { + "type": "keyword" + }, + "apiKey": { + "type": "binary" + }, + "apiKeyOwner": { + "type": "keyword" + }, + "consumer": { + "type": "keyword" + }, + "createdAt": { + "type": "date" + }, + "legacyId": { + "type": "keyword" + }, + "createdBy": { + "type": "keyword" + }, + "updatedAt": { + "type": "date" + }, + "executionStatus": { + "properties": { + "error": { + "properties": { + "message": { + "type": "keyword" + }, + "reason": { + "type": "keyword" + } + } + }, + "lastExecutionDate": { + "type": "date" + }, + "status": { + "type": "keyword" + } + } + }, + "enabled": { + "type": "boolean" + }, + "muteAll": { + "type": "boolean" + }, + "mutedInstanceIds": { + "type": "keyword" + }, + "name": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + }, + "params": { + "enabled": false, + "type": "object" + }, + "schedule": { + "properties": { + "interval": { + "type": "keyword" + } + } + }, + "scheduledTaskId": { + "type": "keyword" + }, + "tags": { + "type": "keyword" + }, + "throttle": { + "type": "keyword" + }, + "updatedBy": { + "type": "keyword" + } + } + }, + "legacy-url-alias": { + "properties": { + "sourceId": { + "type": "text" + }, + "targetNamespace": { + "type": "keyword" + }, + "targetType": { + "type": "keyword" + }, + "targetId": { + "type": "keyword" + }, + "resolveCounter": { + "type": "integer" + }, + "lastResolved": { + "type": "date" + } + } + }, + "config": { + "dynamic": "true", + "properties": { + "buildNum": { + "type": "keyword" + } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "alert": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "config": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "space": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "namespace": { + "type": "keyword" + }, + "namespaces": { + "type": "keyword" + }, + "originId": { + "type": "keyword" + }, + "coreMigrationVersion": { + "type": "keyword" + }, + "query": { + "properties": { + "description": { + "type": "text" + }, + "filters": { + "enabled": false, + "type": "object" + }, + "query": { + "properties": { + "language": { + "type": "keyword" + }, + "query": { + "index": false, + "type": "keyword" + } + } + }, + "timefilter": { + "enabled": false, + "type": "object" + }, + "title": { + "type": "text" + } + } + }, + "references": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + }, + "type": "nested" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } + } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "imageUrl": { + "index": false, + "type": "text" + }, + "initials": { + "type": "keyword" + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_replicas": "1", + "number_of_shards": "1" + } + } + } +} diff --git a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json index 7561dbb8dc6d2..7292878908cab 100644 --- a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json +++ b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json @@ -276,27 +276,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space/mappings.json b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space/mappings.json index 0fa5a458f6995..45206c84b69de 100644 --- a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space/mappings.json +++ b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space/mappings.json @@ -273,27 +273,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, @@ -3089,4 +3085,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/visualize/default/mappings.json b/x-pack/test/functional/es_archives/visualize/default/mappings.json index 00dddbcafdd1c..abf6bcfa04c80 100644 --- a/x-pack/test/functional/es_archives/visualize/default/mappings.json +++ b/x-pack/test/functional/es_archives/visualize/default/mappings.json @@ -254,27 +254,23 @@ }, "apm-indices": { "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } + "error": { + "type": "keyword" + }, + "metric": { + "type": "keyword" + }, + "onboarding": { + "type": "keyword" + }, + "sourcemap": { + "type": "keyword" + }, + "span": { + "type": "keyword" + }, + "transaction": { + "type": "keyword" } } }, diff --git a/x-pack/test/functional/page_objects/reporting_page.ts b/x-pack/test/functional/page_objects/reporting_page.ts index 552d2c9c831bd..039f4ff0fbc57 100644 --- a/x-pack/test/functional/page_objects/reporting_page.ts +++ b/x-pack/test/functional/page_objects/reporting_page.ts @@ -19,6 +19,7 @@ export class ReportingPageObject extends FtrService { private readonly retry = this.ctx.getService('retry'); private readonly security = this.ctx.getService('security'); private readonly testSubjects = this.ctx.getService('testSubjects'); + private readonly find = this.ctx.getService('find'); private readonly share = this.ctx.getPageObject('share'); private readonly timePicker = this.ctx.getPageObject('timePicker'); @@ -33,15 +34,21 @@ export class ReportingPageObject extends FtrService { async getReportURL(timeout: number) { this.log.debug('getReportURL'); - const url = await this.testSubjects.getAttribute( - 'downloadCompletedReportButton', - 'href', - timeout - ); - - this.log.debug(`getReportURL got url: ${url}`); - - return url; + try { + const url = await this.testSubjects.getAttribute( + 'downloadCompletedReportButton', + 'href', + timeout + ); + this.log.debug(`getReportURL got url: ${url}`); + + return url; + } catch (err) { + const errorTextEl = await this.find.byCssSelector('[data-test-errorText]'); + const errorText = await errorTextEl.getAttribute('data-test-errorText'); + const newError = new Error(`Test report failed: ${errorText}: ${err}`); + throw newError; + } } async removeForceSharedItemsContainerSize() { diff --git a/x-pack/test/functional/services/monitoring/cluster_overview.js b/x-pack/test/functional/services/monitoring/cluster_overview.js index 7e888d6233ff7..215e92fa055be 100644 --- a/x-pack/test/functional/services/monitoring/cluster_overview.js +++ b/x-pack/test/functional/services/monitoring/cluster_overview.js @@ -12,8 +12,7 @@ export function MonitoringClusterOverviewProvider({ getService }) { const retry = getService('retry'); const SUBJ_CLUSTER_ALERTS = `clusterAlertsContainer`; - const SUBJ_CLUSTER_OVERVIEW = 'clusterOverviewContainer'; - const SUBJ_CLUSTER_NAME = `${SUBJ_CLUSTER_OVERVIEW} > clusterName`; + const SUBJ_CLUSTER_NAME = `overviewTabsclusterName`; const SUBJ_ES_PANEL = `clusterItemContainerElasticsearch`; const SUBJ_ES_STATUS = `${SUBJ_ES_PANEL} > statusIcon`; diff --git a/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js b/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js index 982b5002a8833..25bfd82f01da7 100644 --- a/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js +++ b/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js @@ -63,6 +63,7 @@ export function MonitoringElasticsearchNodesProvider({ getService, getPageObject async clickNameCol() { await find.clickByCssSelector(`[data-test-subj="${SUBJ_TABLE_SORT_NAME_COL}"] > button`); + await find.byCssSelector('.euiBasicTable-loading'); await this.waitForTableToFinishLoading(); } diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/export_exception_list.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/export_exception_list.ts new file mode 100644 index 0000000000000..d35d34fde5bcc --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/export_exception_list.ts @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import type { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { EXCEPTION_LIST_URL, EXCEPTION_LIST_ITEM_URL } from '@kbn/securitysolution-list-constants'; + +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + removeExceptionListServerGeneratedProperties, + removeExceptionListItemServerGeneratedProperties, + binaryToString, + deleteAllExceptions, +} from '../../utils'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { getCreateExceptionListItemMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('export_exception_list_route', () => { + describe('exporting exception lists', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should set the response content types to be expected', async () => { + // create an exception list + const { body } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create an exception list item + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + await supertest + .post( + `${EXCEPTION_LIST_URL}/_export?id=${body.id}&list_id=${body.list_id}&namespace_type=single` + ) + .set('kbn-xsrf', 'true') + .expect('Content-Disposition', `attachment; filename="${body.list_id}"`) + .expect(200); + }); + + it('should return 404 if given ids that do not exist', async () => { + // create an exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create an exception list item + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const { body: exportBody } = await supertest + .post( + `${EXCEPTION_LIST_URL}/_export?id=not_exist&list_id=not_exist&namespace_type=single` + ) + .set('kbn-xsrf', 'true') + .expect(400); + + expect(exportBody).to.eql({ + message: 'exception list with list_id: not_exist does not exist', + status_code: 400, + }); + }); + + it('should export a single list with a list id', async () => { + const { body } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body: itemBody } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const { body: exportResult } = await supertest + .post( + `${EXCEPTION_LIST_URL}/_export?id=${body.id}&list_id=${body.list_id}&namespace_type=single` + ) + .set('kbn-xsrf', 'true') + .expect(200) + .parse(binaryToString); + + const exportedItemsToArray = exportResult.toString().split('\n'); + const list = JSON.parse(exportedItemsToArray[0]); + const item = JSON.parse(exportedItemsToArray[1]); + + expect(removeExceptionListServerGeneratedProperties(list)).to.eql( + removeExceptionListServerGeneratedProperties(body) + ); + expect(removeExceptionListItemServerGeneratedProperties(item)).to.eql( + removeExceptionListItemServerGeneratedProperties(itemBody) + ); + }); + + it('should export two list items with a list id', async () => { + const { body } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const secondExceptionListItem: CreateExceptionListItemSchema = { + ...getCreateExceptionListItemMinimalSchemaMock(), + item_id: 'some-list-item-id-2', + }; + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(secondExceptionListItem) + .expect(200); + + const { body: exportResult } = await supertest + .post( + `${EXCEPTION_LIST_URL}/_export?id=${body.id}&list_id=${body.list_id}&namespace_type=single` + ) + .set('kbn-xsrf', 'true') + .expect(200) + .parse(binaryToString); + + const bodyString = exportResult.toString(); + expect(bodyString.includes('some-list-item-id-2')).to.be(true); + expect(bodyString.includes('some-list-item-id')).to.be(true); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts index 89a1183da6790..afb6057dedfff 100644 --- a/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts @@ -24,6 +24,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./find_list_items')); loadTestFile(require.resolve('./import_list_items')); loadTestFile(require.resolve('./export_list_items')); + loadTestFile(require.resolve('./export_exception_list')); loadTestFile(require.resolve('./create_exception_lists')); loadTestFile(require.resolve('./create_exception_list_items')); loadTestFile(require.resolve('./read_exception_lists')); diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/package.ts b/x-pack/test/security_solution_endpoint_api_int/apis/package.ts index a8fd5a612b306..fdacc07426871 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/package.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/package.ts @@ -66,7 +66,8 @@ export default function ({ getService }: FtrProviderContext) { }); }; - describe('Endpoint package', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/114885 + describe.skip('Endpoint package', () => { describe('network processors', () => { let networkIndexData: InsertedEvents; diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 173403743235b..1ffe3834d782d 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -102,7 +102,6 @@ { "path": "../plugins/remote_clusters/tsconfig.json" }, { "path": "../plugins/cross_cluster_replication/tsconfig.json" }, { "path": "../plugins/index_lifecycle_management/tsconfig.json"}, - { "path": "../plugins/uptime/tsconfig.json" }, - { "path": "../plugins/xpack_legacy/tsconfig.json" } + { "path": "../plugins/uptime/tsconfig.json" } ] } diff --git a/yarn.lock b/yarn.lock index 9d141be857475..70e2a452e87dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2389,10 +2389,10 @@ ms "^2.1.3" secure-json-parse "^2.4.0" -"@elastic/ems-client@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.15.0.tgz#c101d7f83aa56463bcc385fd4eb883c6ea3ae9fc" - integrity sha512-BAAAVPhoaH6SGrfuO6U0MVRg4lvblhJ9VqYlMf3dZN9uDBB+12CUtb6t6Kavn5Tr3nS6X3tU/KKsuomo5RrEeQ== +"@elastic/ems-client@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.16.0.tgz#92db94126bac0b95fbf156fe609f68979e7af4b6" + integrity sha512-NgMB5vqj6I7lxVsysrz6eB1EW6gsZj7SWWs79WSiiKQeNuRg82tJhvbHQnWezjIS4UKOtoGxZsg475EHVZB46g== dependencies: "@types/geojson" "^7946.0.7" "@types/lru-cache" "^5.1.0" @@ -2400,7 +2400,7 @@ "@types/topojson-specification" "^1.0.1" lodash "^4.17.15" lru-cache "^6.0.0" - semver "7.3.2" + semver "^7.3.2" topojson-client "^3.1.0" "@elastic/eslint-config-kibana@link:bazel-bin/packages/elastic-eslint-config-kibana": @@ -2412,10 +2412,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@38.0.1": - version "38.0.1" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-38.0.1.tgz#de03c4436cd1b58327f54f57e4248183d681c0f8" - integrity sha512-yzV56rGVwhALnLVXsw2LGsFksh7c27BwIQOl2memDfm15VprzX5Fd+u6TpX8TkpFbTTgnYfyhI11W3eKVUYt1g== +"@elastic/eui@39.0.0": + version "39.0.0" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-39.0.0.tgz#abac19edd466eee13612d5668e5456961dc813b8" + integrity sha512-8sf8sbxjpRxV23dFTwbkaWH6LhWrOlMpdUUMVUC9zd0g5iQLj1IxkxQCeyYM/p++SQFl+1hshAuaH//DCz5Xrw== dependencies: "@types/chroma-js" "^2.0.0" "@types/lodash" "^4.14.160" @@ -7605,10 +7605,10 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -abortcontroller-polyfill@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.4.0.tgz#0d5eb58e522a461774af8086414f68e1dda7a6c4" - integrity sha512-3ZFfCRfDzx3GFjO6RAkYx81lPGpUS20ISxux9gLxuKnqafNcFQo59+IoZqpO2WvQlyc287B62HDnDdNYRmlvWA== +abortcontroller-polyfill@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" + integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" @@ -9774,18 +9774,7 @@ browserslist@4.14.2: escalade "^3.0.2" node-releases "^1.1.61" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1, browserslist@^4.6.0, browserslist@^4.8.5: - version "4.16.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" - integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== - dependencies: - caniuse-lite "^1.0.30001181" - colorette "^1.2.1" - electron-to-chromium "^1.3.649" - escalade "^3.1.1" - node-releases "^1.1.70" - -browserslist@^4.16.6, browserslist@^4.17.1: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1, browserslist@^4.16.6, browserslist@^4.17.1, browserslist@^4.6.0, browserslist@^4.8.5: version "4.17.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.1.tgz#a98d104f54af441290b7d592626dd541fa642eb9" integrity sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ== @@ -10128,12 +10117,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001097, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181: - version "1.0.30001258" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001258.tgz" - integrity sha512-RBByOG6xWXUp0CR2/WU2amXz3stjKpSl5J1xU49F1n2OxD//uBZO4wCKUiG+QMGf7CHGfDDcqoKriomoGVxTeA== - -caniuse-lite@^1.0.30001259: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001097, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001259: version "1.0.30001261" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001261.tgz#96d89813c076ea061209a4e040d8dcf0c66a1d01" integrity sha512-vM8D9Uvp7bHIN0fZ2KQ4wnmYFpJo/Etb4Vwsuc+ka0tfGDHvOPrFm6S/7CCNLSOkAUjenT2HnUPESdOIL91FaA== @@ -11231,15 +11215,10 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.9: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== - -core-js@^3.8.2: - version "3.11.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.11.0.tgz#05dac6aa70c0a4ad842261f8957b961d36eb8926" - integrity sha512-bd79DPpx+1Ilh9+30aT5O1sgpQd4Ttg8oqkqi51ZzhedMM1omD2e6IOF48Z/DzDCZ2svp49tN/3vneTK6ZBkXw== +core-js@^3.0.1, core-js@^3.0.4, core-js@^3.18.3, core-js@^3.6.5, core-js@^3.8.2: + version "3.18.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.3.tgz#86a0bba2d8ec3df860fefcc07a8d119779f01509" + integrity sha512-tReEhtMReZaPFVw7dajMx0vlsz3oOb8ajgPoHVYGxr8ErnZ6PcYEvvmjGmXlfpnxpkYSdOQttjB+MvVbCGfvLw== core-util-is@1.0.2, core-util-is@^1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -13273,11 +13252,6 @@ electron-to-chromium@^1.3.564: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.642.tgz#8b884f50296c2ae2a9997f024d0e3e57facc2b94" integrity sha512-cev+jOrz/Zm1i+Yh334Hed6lQVOkkemk2wRozfMF4MtTR7pxf3r3L5Rbd7uX1zMcEqVJ7alJBnJL7+JffkC6FQ== -electron-to-chromium@^1.3.649: - version "1.3.690" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.690.tgz#54df63ec42fba6b8e9e05fe4be52caeeedb6e634" - integrity sha512-zPbaSv1c8LUKqQ+scNxJKv01RYFkVVF1xli+b+3Ty8ONujHjAMg+t/COmdZqrtnS1gT+g4hbSodHillymt1Lww== - electron-to-chromium@^1.3.846: version "1.3.853" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.853.tgz#f3ed1d31f092cb3a17af188bca6c6a3ec91c3e82" @@ -21199,11 +21173,6 @@ node-releases@^1.1.61: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== -node-releases@^1.1.70: - version "1.1.71" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" - integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== - node-releases@^1.1.76: version "1.1.76" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.76.tgz#df245b062b0cafbd5282ab6792f7dccc2d97f36e" @@ -23229,7 +23198,7 @@ printj@~1.1.0: resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== -prismjs@^1.22.0, prismjs@~1.24.0, prismjs@~1.25.0: +prismjs@^1.22.0, prismjs@~1.25.0: version "1.25.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== @@ -24782,13 +24751,13 @@ reflect.ownkeys@^0.2.0: integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= refractor@^3.2.0, refractor@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.4.0.tgz#62bd274b06c942041f390c371b676eb67cb0a678" - integrity sha512-dBeD02lC5eytm9Gld2Mx0cMcnR+zhSnsTfPpWqFaMgUMJfC9A6bcN3Br/NaXrnBJcuxnLFR90k1jrkaSyV8umg== + version "3.5.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.5.0.tgz#334586f352dda4beaf354099b48c2d18e0819aec" + integrity sha512-QwPJd3ferTZ4cSPPjdP5bsYHMytwWYnAN5EEnLtGvkqp/FCCnGsBgxrm9EuIDnjUC3Uc/kETtvVi7fSIVC74Dg== dependencies: hastscript "^6.0.0" parse-entities "^2.0.0" - prismjs "~1.24.0" + prismjs "~1.25.0" regedit@^3.0.3: version "3.0.3" @@ -25271,7 +25240,7 @@ reselect@^4.0.0: resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== -resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1: +resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== @@ -25841,16 +25810,16 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2, semver@^7.2.1, semver@^7.3.2, semver@~7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.2.1, semver@^7.3.2, semver@~7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"