From ee3af609851dccde2f4b9861ae9ea48848924beb Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 02:16:05 +1100
Subject: [PATCH 01/12] [8.16] [ML] Fixes link to anomaly explorer from anomaly
embeddables when viewing by job group (#198256) (#198513)
# Backport
This will backport the following commits from `main` to `8.16`:
- [[ML] Fixes link to anomaly explorer from anomaly embeddables when
viewing by job group
(#198256)](https://github.com/elastic/kibana/pull/198256)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: Robert Jaszczurek <92210485+rbrtj@users.noreply.github.com>
---
.../job_selector/use_job_selection.ts | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugins/ml/public/application/components/job_selector/use_job_selection.ts b/x-pack/plugins/ml/public/application/components/job_selector/use_job_selection.ts
index 7fcc1e71e1808..51d1882084d3e 100644
--- a/x-pack/plugins/ml/public/application/components/job_selector/use_job_selection.ts
+++ b/x-pack/plugins/ml/public/application/components/job_selector/use_job_selection.ts
@@ -25,6 +25,24 @@ function getInvalidJobIds(jobs: MlJobWithTimeRange[], ids: string[]) {
});
}
+// This is useful when redirecting from dashboards where groupIds are treated as jobIds
+const getJobIdsFromGroups = (jobIds: string[], jobs: MlJobWithTimeRange[]) => {
+ const result = new Set();
+
+ jobIds.forEach((id) => {
+ const jobsInGroup = jobs.filter((job) => job.groups?.includes(id));
+
+ if (jobsInGroup.length > 0) {
+ jobsInGroup.forEach((job) => result.add(job.job_id));
+ } else {
+ // If it's not a group ID, keep it (regardless of whether it's valid or not)
+ result.add(id);
+ }
+ });
+
+ return Array.from(result);
+};
+
export interface JobSelection {
jobIds: string[];
selectedGroups: string[];
@@ -37,9 +55,9 @@ export const useJobSelection = (jobs: MlJobWithTimeRange[]) => {
const getJobSelection = useJobSelectionFlyout();
const tmpIds = useMemo(() => {
- const ids = globalState?.ml?.jobIds || [];
+ const ids = getJobIdsFromGroups(globalState?.ml?.jobIds || [], jobs);
return (typeof ids === 'string' ? [ids] : ids).map((id: string) => String(id));
- }, [globalState?.ml?.jobIds]);
+ }, [globalState?.ml?.jobIds, jobs]);
const invalidIds = useMemo(() => {
return getInvalidJobIds(jobs, tmpIds);
From fa80dc245d94173784b436e40ec99d3ba5340241 Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 02:42:37 +1100
Subject: [PATCH 02/12] [8.16] [Search][Connectors] Validating connectors name
(#198483) (#198537)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
# Backport
This will backport the following commits from `main` to `8.16`:
- [[Search][Connectors] Validating connectors name
(#198483)](https://github.com/elastic/kibana/pull/198483)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: José Luis González
---
.../create_connector/start_step.tsx | 89 +++++++++++++++++--
1 file changed, 80 insertions(+), 9 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx
index 9a93b43f6b751..7e23474b207f1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx
@@ -27,6 +27,7 @@ import {
import { i18n } from '@kbn/i18n';
import * as Constants from '../../../../shared/constants';
+import { isValidIndexName } from '../../../utils/validate_index_name';
import { GeneratedConfigFields } from '../../connector_detail/components/generated_config_fields';
import { ConnectorViewLogic } from '../../connector_detail/connector_view_logic';
@@ -71,6 +72,18 @@ export const StartStep: React.FC = ({
setRawName(e.target.value);
};
+ const formError = isValidIndexName(rawName)
+ ? error
+ : i18n.translate(
+ 'xpack.enterpriseSearch.createConnector.startStep.euiFormRow.nameInputHelpText.lineOne',
+ {
+ defaultMessage: '{connectorName} is an invalid index name',
+ values: {
+ connectorName: rawName,
+ },
+ }
+ );
+
return (
@@ -100,6 +113,22 @@ export const StartStep: React.FC = ({
'xpack.enterpriseSearch.createConnector.startStep.euiFormRow.connectorNameLabel',
{ defaultMessage: 'Connector name' }
)}
+ helpText={
+ <>
+
+ {formError}
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.startStep.namesShouldBeLowercaseTextLabel',
+ {
+ defaultMessage:
+ 'The connector name should be lowercase and cannot contain spaces or special characters.',
+ }
+ )}
+
+ >
+ }
>
= ({
'xpack.enterpriseSearch.createConnector.startStep.euiFormRow.descriptionLabel',
{ defaultMessage: 'Description' }
)}
+ labelAppend={
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.createConnector.startStep.euiFormRow.descriptionLabelAppend',
+ { defaultMessage: 'Optional' }
+ )}
+
+ }
>
= ({
hasShadow={false}
hasBorder
paddingSize="l"
- color={selectedConnector?.name ? 'plain' : 'subdued'}
+ color={
+ selectedConnector?.name && isValidIndexName(rawName) && !error ? 'plain' : 'subdued'
+ }
>
-
+
{i18n.translate(
'xpack.enterpriseSearch.createConnector.startStep.h4.deploymentLabel',
@@ -218,7 +263,10 @@ export const StartStep: React.FC = ({
-
+
{i18n.translate(
'xpack.enterpriseSearch.createConnector.startStep.p.youWillStartTheLabel',
@@ -242,7 +290,7 @@ export const StartStep: React.FC = ({
}
}}
fill
- disabled={!canConfigureConnector}
+ disabled={!canConfigureConnector || !isValidIndexName(rawName) || Boolean(error)}
isLoading={isCreateLoading || isGenerateLoading}
>
{Constants.NEXT_BUTTON_LABEL}
@@ -252,12 +300,20 @@ export const StartStep: React.FC = ({
) : (
-
+
{i18n.translate(
'xpack.enterpriseSearch.createConnector.startStep.h4.configureIndexAndAPILabel',
@@ -268,7 +324,14 @@ export const StartStep: React.FC = ({
-
+
{i18n.translate(
'xpack.enterpriseSearch.createConnector.startStep.p.thisProcessWillCreateLabel',
@@ -309,7 +372,9 @@ export const StartStep: React.FC = ({
= ({
From 7dbd7c79a04b2c676a97a144c3e986968e5bbcbe Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 03:36:34 +1100
Subject: [PATCH 03/12] [8.16] Update
docker.elastic.co/wolfi/chainguard-base:latest Docker digest to 7082adc
(main) (#198500) (#198542)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
# Backport
This will backport the following commits from `main` to `8.16`:
- [Update docker.elastic.co/wolfi/chainguard-base:latest Docker digest
to 7082adc (main)
(#198500)](https://github.com/elastic/kibana/pull/198500)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
If you
want to rebase/retry this PR, check\r\nthis box\r\n\r\n---\r\n\r\nThis
PR has been generated by
[Renovate\r\nBot](https://togithub.com/renovatebot/renovate).\r\n\r\n\r\n\r\nCo-authored-by:
elastic-renovate-prod[bot]
<174716857+elastic-renovate-prod[bot]@users.noreply.github.com>","sha":"923f2feb2d4941776d3bfaa59aaf392c143eef5f","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Operations","release_note:skip","v9.0.0","backport:prev-minor","v8.16.0"],"title":"Update
docker.elastic.co/wolfi/chainguard-base:latest Docker digest to 7082adc
(main)","number":198500,"url":"https://github.com/elastic/kibana/pull/198500","mergeCommit":{"message":"Update
docker.elastic.co/wolfi/chainguard-base:latest Docker digest to 7082adc
(main) (#198500)\n\nThis PR contains the following updates:\r\n\r\n|
Package | Update | Change |\r\n|---|---|---|\r\n|
docker.elastic.co/wolfi/chainguard-base | digest | `8cff240`
->\r\n`7082adc` |\r\n\r\n---\r\n\r\n### Configuration\r\n\r\n📅
**Schedule**: Branch creation - At any time (no schedule
defined),\r\nAutomerge - At any time (no schedule defined).\r\n\r\n🚦
**Automerge**: Disabled by config. Please merge this manually once
you\r\nare satisfied.\r\n\r\n♻ **Rebasing**: Whenever PR becomes
conflicted, or you tick the\r\nrebase/retry checkbox.\r\n\r\n🔕
**Ignore**: Close this PR and you won't be reminded about this
update\r\nagain.\r\n\r\n---\r\n\r\n- [ ] If you
want to rebase/retry this PR, check\r\nthis box\r\n\r\n---\r\n\r\nThis
PR has been generated by
[Renovate\r\nBot](https://togithub.com/renovatebot/renovate).\r\n\r\n\r\n\r\nCo-authored-by:
elastic-renovate-prod[bot]
<174716857+elastic-renovate-prod[bot]@users.noreply.github.com>","sha":"923f2feb2d4941776d3bfaa59aaf392c143eef5f"}},"sourceBranch":"main","suggestedTargetBranches":["8.16"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/198500","number":198500,"mergeCommit":{"message":"Update
docker.elastic.co/wolfi/chainguard-base:latest Docker digest to 7082adc
(main) (#198500)\n\nThis PR contains the following updates:\r\n\r\n|
Package | Update | Change |\r\n|---|---|---|\r\n|
docker.elastic.co/wolfi/chainguard-base | digest | `8cff240`
->\r\n`7082adc` |\r\n\r\n---\r\n\r\n### Configuration\r\n\r\n📅
**Schedule**: Branch creation - At any time (no schedule
defined),\r\nAutomerge - At any time (no schedule defined).\r\n\r\n🚦
**Automerge**: Disabled by config. Please merge this manually once
you\r\nare satisfied.\r\n\r\n♻ **Rebasing**: Whenever PR becomes
conflicted, or you tick the\r\nrebase/retry checkbox.\r\n\r\n🔕
**Ignore**: Close this PR and you won't be reminded about this
update\r\nagain.\r\n\r\n---\r\n\r\n- [ ] If you
want to rebase/retry this PR, check\r\nthis box\r\n\r\n---\r\n\r\nThis
PR has been generated by
[Renovate\r\nBot](https://togithub.com/renovatebot/renovate).\r\n\r\n\r\n\r\nCo-authored-by:
elastic-renovate-prod[bot]
<174716857+elastic-renovate-prod[bot]@users.noreply.github.com>","sha":"923f2feb2d4941776d3bfaa59aaf392c143eef5f"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
Co-authored-by: elastic-renovate-prod[bot] <174716857+elastic-renovate-prod[bot]@users.noreply.github.com>
---
src/dev/build/tasks/os_packages/docker_generator/run.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.ts b/src/dev/build/tasks/os_packages/docker_generator/run.ts
index c810a74091458..85cd6d7458ba9 100644
--- a/src/dev/build/tasks/os_packages/docker_generator/run.ts
+++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts
@@ -51,7 +51,7 @@ export async function runDockerGenerator(
*/
if (flags.baseImage === 'wolfi')
baseImageName =
- 'docker.elastic.co/wolfi/chainguard-base:latest@sha256:8cff240b81057968575dd28dab0c3609657cb7e0e60ff017261e5b721fad9e1b';
+ 'docker.elastic.co/wolfi/chainguard-base:latest@sha256:7082adcc2c4380be273ab5b80c4a762b4f17279c13c6fc8f87a60190aee2e2cd';
let imageFlavor = '';
if (flags.baseImage === 'ubi') imageFlavor += `-ubi`;
From 6d6852dcd9309996dcb79ef0f711c1a765e08092 Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 04:18:34 +1100
Subject: [PATCH 04/12] [8.16] [ML] Fix Trained model deletion with expanded
row (#198530) (#198567)
# Backport
This will backport the following commits from `main` to `8.16`:
- [[ML] Fix Trained model deletion with expanded row
(#198530)](https://github.com/elastic/kibana/pull/198530)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: Dima Arnautov
---
.../public/application/model_management/models_list.tsx | 8 ++++++++
.../apps/ml/short_tests/model_management/model_list.ts | 3 ++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/ml/public/application/model_management/models_list.tsx b/x-pack/plugins/ml/public/application/model_management/models_list.tsx
index 9dbdf6069aff6..a717995d4ee14 100644
--- a/x-pack/plugins/ml/public/application/model_management/models_list.tsx
+++ b/x-pack/plugins/ml/public/application/model_management/models_list.tsx
@@ -957,6 +957,14 @@ export const ModelsList: FC = ({
}
});
+ setItemIdToExpandedRowMap((prev) => {
+ const newMap = { ...prev };
+ modelsToDelete.forEach((model) => {
+ delete newMap[model.model_id];
+ });
+ return newMap;
+ });
+
setModelsToDelete([]);
if (refreshList) {
diff --git a/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts b/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts
index c828e8da1f3af..7977f17bf5f65 100644
--- a/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts
+++ b/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts
@@ -416,7 +416,8 @@ export default function ({ getService }: FtrProviderContext) {
it('displays a model without an ingest pipeline and model can be deleted', async () => {
await ml.testExecution.logTestStep('should display the model in the table');
- await ml.trainedModelsTable.filterWithSearchString(modelWithoutPipelineData.modelId, 1);
+ await ml.testExecution.logTestStep('expands the row to show the model details');
+ await ml.trainedModelsTable.ensureRowIsExpanded(modelWithoutPipelineData.modelId);
await ml.testExecution.logTestStep(
'displays expected row values for the model in the table'
From 50a48136517328cd32c0a114e7a29eb982cda869 Mon Sep 17 00:00:00 2001
From: Jon
Date: Thu, 31 Oct 2024 12:23:30 -0500
Subject: [PATCH 05/12] [8.16][ci] Run type checking before tests (#197539)
(#198425)
#197539
---
.buildkite/pipelines/on_merge.yml | 95 ++++---------------
.../pipelines/pull_request/apm_cypress.yml | 1 +
.buildkite/pipelines/pull_request/base.yml | 28 +++---
.../pipelines/pull_request/deploy_cloud.yml | 1 +
.../pull_request/exploratory_view_plugin.yml | 1 +
.buildkite/pipelines/pull_request/fips.yml | 1 +
.../pipelines/pull_request/fleet_cypress.yml | 1 +
.../pipelines/pull_request/kbn_handlebars.yml | 1 +
.../observability_onboarding_cypress.yml | 1 +
.../pull_request/profiling_cypress.yml | 1 +
.../pipelines/pull_request/response_ops.yml | 1 +
.../pull_request/response_ops_cases.yml | 1 +
.../security_solution/ai_assistant.yml | 1 +
.../cloud_security_posture.yml | 2 +
.../security_solution/cypress_burn.yml | 3 +
.../security_solution/defend_workflows.yml | 1 +
.../security_solution/detection_engine.yml | 2 +
.../security_solution/entity_analytics.yml | 1 +
.../security_solution/explore.yml | 1 +
.../security_solution/investigations.yml | 1 +
.../security_solution/osquery_cypress.yml | 1 +
.../security_solution/playwright.yml | 1 +
.../security_solution/rule_management.yml | 2 +
.../pipelines/pull_request/slo_plugin_e2e.yml | 1 +
.../pull_request/synthetics_plugin.yml | 1 +
.../pipelines/pull_request/uptime_plugin.yml | 1 +
.../pipelines/pull_request/ux_plugin_e2e.yml | 1 +
27 files changed, 62 insertions(+), 91 deletions(-)
diff --git a/.buildkite/pipelines/on_merge.yml b/.buildkite/pipelines/on_merge.yml
index 3705a2c902642..df3a74270677f 100644
--- a/.buildkite/pipelines/on_merge.yml
+++ b/.buildkite/pipelines/on_merge.yml
@@ -39,7 +39,6 @@ steps:
provider: gcp
machineType: n2-highcpu-8
preemptible: true
- key: quick_checks
timeout_in_minutes: 60
retry:
automatic:
@@ -54,7 +53,6 @@ steps:
provider: gcp
machineType: n2-standard-16
preemptible: true
- key: linting
timeout_in_minutes: 60
retry:
automatic:
@@ -69,8 +67,23 @@ steps:
provider: gcp
machineType: n2-standard-32
preemptible: true
- key: linting_with_types
- timeout_in_minutes: 90
+ timeout_in_minutes: 60
+ retry:
+ automatic:
+ - exit_status: '-1'
+ limit: 3
+
+ - command: .buildkite/scripts/steps/check_types.sh
+ label: 'Check Types'
+ agents:
+ image: family/kibana-ubuntu-2004
+ imageProject: elastic-images-prod
+ provider: gcp
+ machineType: c4-standard-4
+ diskType: 'hyperdisk-balanced'
+ preemptible: true
+ spotZones: us-central1-a,us-central1-b,us-central1-c
+ timeout_in_minutes: 60
retry:
automatic:
- exit_status: '-1'
@@ -136,11 +149,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 2
retry:
@@ -156,11 +164,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 4
retry:
@@ -176,11 +179,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 6
retry:
@@ -196,11 +194,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 5
retry:
@@ -216,11 +209,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 6
retry:
@@ -236,11 +224,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 1
retry:
@@ -256,11 +239,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 2
retry:
@@ -276,11 +254,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 2
retry:
@@ -296,11 +269,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 6
retry:
@@ -316,11 +284,6 @@ steps:
provider: gcp
machineType: n2-standard-4
preemptible: true
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 8
retry:
@@ -338,11 +301,6 @@ steps:
localSsds: 1
localSsdInterface: nvme
machineType: n2-standard-4
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
timeout_in_minutes: 60
parallelism: 20
retry:
@@ -353,11 +311,6 @@ steps:
- command: '.buildkite/scripts/steps/functional/on_merge_unsupported_ftrs.sh'
label: Trigger unsupported ftr tests
timeout_in_minutes: 10
- depends_on:
- - build
- - quick_checks
- - linting
- - linting_with_types
agents:
image: family/kibana-ubuntu-2004
imageProject: elastic-images-prod
@@ -378,20 +331,6 @@ steps:
- exit_status: '-1'
limit: 3
- - command: .buildkite/scripts/steps/check_types.sh
- label: 'Check Types'
- agents:
- image: family/kibana-ubuntu-2004
- imageProject: elastic-images-prod
- provider: gcp
- machineType: n2-standard-4
- preemptible: true
- timeout_in_minutes: 70
- retry:
- automatic:
- - exit_status: '-1'
- limit: 3
-
- command: .buildkite/scripts/steps/checks/capture_oas_snapshot.sh
label: 'Check OAS Snapshot'
agents:
diff --git a/.buildkite/pipelines/pull_request/apm_cypress.yml b/.buildkite/pipelines/pull_request/apm_cypress.yml
index 9d2cca6d9d452..c0cb60dbc986b 100644
--- a/.buildkite/pipelines/pull_request/apm_cypress.yml
+++ b/.buildkite/pipelines/pull_request/apm_cypress.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 120
parallelism: 1 # TODO: Set parallelism when apm_cypress handles it
retry:
diff --git a/.buildkite/pipelines/pull_request/base.yml b/.buildkite/pipelines/pull_request/base.yml
index fdc80e6cb8595..54840cb43c65f 100644
--- a/.buildkite/pipelines/pull_request/base.yml
+++ b/.buildkite/pipelines/pull_request/base.yml
@@ -50,7 +50,21 @@ steps:
machineType: n2-standard-32
preemptible: true
key: linting_with_types
- timeout_in_minutes: 90
+ timeout_in_minutes: 60
+ retry:
+ automatic:
+ - exit_status: '-1'
+ limit: 3
+
+ - command: .buildkite/scripts/steps/check_types.sh
+ label: 'Check Types'
+ agents:
+ machineType: c4-standard-4
+ diskType: 'hyperdisk-balanced'
+ preemptible: true
+ spotZones: us-central1-a,us-central1-b,us-central1-c
+ key: check_types
+ timeout_in_minutes: 60
retry:
automatic:
- exit_status: '-1'
@@ -85,18 +99,6 @@ steps:
- exit_status: '*'
limit: 1
- - command: .buildkite/scripts/steps/check_types.sh
- label: 'Check Types'
- agents:
- machineType: n2-standard-4
- preemptible: true
- key: check_types
- timeout_in_minutes: 70
- retry:
- automatic:
- - exit_status: '-1'
- limit: 3
-
- command: .buildkite/scripts/steps/checks.sh
label: 'Checks'
key: checks
diff --git a/.buildkite/pipelines/pull_request/deploy_cloud.yml b/.buildkite/pipelines/pull_request/deploy_cloud.yml
index e82d1ef2e494c..6b42037b95953 100644
--- a/.buildkite/pipelines/pull_request/deploy_cloud.yml
+++ b/.buildkite/pipelines/pull_request/deploy_cloud.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 30
soft_fail: true
retry:
diff --git a/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml b/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml
index 42aaf59b1c1f2..c46edb528987a 100644
--- a/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml
+++ b/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
artifact_paths:
- 'x-pack/plugins/observability_solution/exploratory_view/e2e/.journeys/**/*'
diff --git a/.buildkite/pipelines/pull_request/fips.yml b/.buildkite/pipelines/pull_request/fips.yml
index 3fa0ed9bd2062..1a759e1288328 100644
--- a/.buildkite/pipelines/pull_request/fips.yml
+++ b/.buildkite/pipelines/pull_request/fips.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
soft_fail: true
retry:
diff --git a/.buildkite/pipelines/pull_request/fleet_cypress.yml b/.buildkite/pipelines/pull_request/fleet_cypress.yml
index 071106209caaa..d20591728b788 100644
--- a/.buildkite/pipelines/pull_request/fleet_cypress.yml
+++ b/.buildkite/pipelines/pull_request/fleet_cypress.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 50
parallelism: 6
retry:
diff --git a/.buildkite/pipelines/pull_request/kbn_handlebars.yml b/.buildkite/pipelines/pull_request/kbn_handlebars.yml
index ad338ec425a04..36901a5d5c552 100644
--- a/.buildkite/pipelines/pull_request/kbn_handlebars.yml
+++ b/.buildkite/pipelines/pull_request/kbn_handlebars.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 5
retry:
automatic:
diff --git a/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml b/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml
index d0afe1cd138da..8906cc72fa81f 100644
--- a/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml
+++ b/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 120
retry:
automatic:
diff --git a/.buildkite/pipelines/pull_request/profiling_cypress.yml b/.buildkite/pipelines/pull_request/profiling_cypress.yml
index 2b86cffe75fa6..100e42206b3a1 100644
--- a/.buildkite/pipelines/pull_request/profiling_cypress.yml
+++ b/.buildkite/pipelines/pull_request/profiling_cypress.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 120
parallelism: 2
retry:
diff --git a/.buildkite/pipelines/pull_request/response_ops.yml b/.buildkite/pipelines/pull_request/response_ops.yml
index a5c9b27ee7ecf..f09beb168259f 100644
--- a/.buildkite/pipelines/pull_request/response_ops.yml
+++ b/.buildkite/pipelines/pull_request/response_ops.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 120
parallelism: 9
retry:
diff --git a/.buildkite/pipelines/pull_request/response_ops_cases.yml b/.buildkite/pipelines/pull_request/response_ops_cases.yml
index 994fbb6c4963a..5382ab6017fa6 100644
--- a/.buildkite/pipelines/pull_request/response_ops_cases.yml
+++ b/.buildkite/pipelines/pull_request/response_ops_cases.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 120
retry:
automatic:
diff --git a/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml b/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml
index 6b87f41d585f8..de0cf4daefe73 100644
--- a/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 1
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml b/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml
index 93fad6eecf167..d2f1571f9d93f 100644
--- a/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 1
retry:
@@ -26,6 +27,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 1
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml b/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml
index 1ba22d058e6c1..fc9fab0dec2ae 100644
--- a/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml
@@ -11,6 +11,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
soft_fail: true
parallelism: 1
@@ -27,6 +28,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 1
retry:
@@ -43,6 +45,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 50
soft_fail: true
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml b/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml
index ea7613fd81cba..e8b399ed3ef60 100644
--- a/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml
@@ -11,6 +11,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 20
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml b/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml
index f18d187aab9e7..e879d2ad267f0 100644
--- a/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 5
retry:
@@ -26,6 +27,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 2
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml b/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml
index 16e1860a1453c..4e74af8f80742 100644
--- a/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 2
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/explore.yml b/.buildkite/pipelines/pull_request/security_solution/explore.yml
index 5fa4229e7dbde..5121899c17a59 100644
--- a/.buildkite/pipelines/pull_request/security_solution/explore.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/explore.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 2
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/investigations.yml b/.buildkite/pipelines/pull_request/security_solution/investigations.yml
index 469f6d7a2c159..f33634118fad2 100644
--- a/.buildkite/pipelines/pull_request/security_solution/investigations.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/investigations.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 7
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml b/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml
index cb04f1559f3b1..8d7650e93647c 100644
--- a/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 8
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/playwright.yml b/.buildkite/pipelines/pull_request/security_solution/playwright.yml
index 98a939570b1be..3255d3b3203c7 100644
--- a/.buildkite/pipelines/pull_request/security_solution/playwright.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/playwright.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 1
retry:
diff --git a/.buildkite/pipelines/pull_request/security_solution/rule_management.yml b/.buildkite/pipelines/pull_request/security_solution/rule_management.yml
index 887e1c8597af7..f49a96da39a89 100644
--- a/.buildkite/pipelines/pull_request/security_solution/rule_management.yml
+++ b/.buildkite/pipelines/pull_request/security_solution/rule_management.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 4
retry:
@@ -26,6 +27,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
parallelism: 2
retry:
diff --git a/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml b/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml
index 025c80809ab35..3d1a4f9b46f41 100644
--- a/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml
+++ b/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 30
artifact_paths:
- 'x-pack/plugins/observability_solution/slo/e2e/.journeys/**/*'
diff --git a/.buildkite/pipelines/pull_request/synthetics_plugin.yml b/.buildkite/pipelines/pull_request/synthetics_plugin.yml
index 0707650aa7c01..f5d6b841a953d 100644
--- a/.buildkite/pipelines/pull_request/synthetics_plugin.yml
+++ b/.buildkite/pipelines/pull_request/synthetics_plugin.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
artifact_paths:
- 'x-pack/plugins/observability_solution/synthetics/e2e/.journeys/**/*'
diff --git a/.buildkite/pipelines/pull_request/uptime_plugin.yml b/.buildkite/pipelines/pull_request/uptime_plugin.yml
index 33a529739ae6f..a03915ef77099 100644
--- a/.buildkite/pipelines/pull_request/uptime_plugin.yml
+++ b/.buildkite/pipelines/pull_request/uptime_plugin.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
artifact_paths:
- 'x-pack/plugins/observability_solution/synthetics/e2e/.journeys/**/*'
diff --git a/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml b/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml
index 977701cc99485..cd95f44fa2e86 100644
--- a/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml
+++ b/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml
@@ -9,6 +9,7 @@ steps:
- quick_checks
- linting
- linting_with_types
+ - check_types
timeout_in_minutes: 60
artifact_paths:
- 'x-pack/plugins/observability_solution/ux/e2e/.journeys/**/*'
From 8b7d1860423b3d57cfb74c9ea87050a1f2b4fa0a Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 05:19:14 +1100
Subject: [PATCH 06/12] [8.16] [EDR Workflows] Fix alert_test.cy.ts flakiness
(#198516) (#198575)
# Backport
This will backport the following commits from `main` to `8.16`:
- [[EDR Workflows] Fix alert_test.cy.ts flakiness
(#198516)](https://github.com/elastic/kibana/pull/198516)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: Tomasz Ciecierski
---
x-pack/plugins/osquery/cypress/e2e/roles/alert_test.cy.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/x-pack/plugins/osquery/cypress/e2e/roles/alert_test.cy.ts b/x-pack/plugins/osquery/cypress/e2e/roles/alert_test.cy.ts
index b332951b1a444..2eaf015f23220 100644
--- a/x-pack/plugins/osquery/cypress/e2e/roles/alert_test.cy.ts
+++ b/x-pack/plugins/osquery/cypress/e2e/roles/alert_test.cy.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { waitForAlertsToPopulate } from '@kbn/test-suites-xpack/security_solution_cypress/cypress/tasks/create_new_rule';
import { disableNewFeaturesTours } from '../../tasks/navigation';
import { initializeDataViews } from '../../tasks/login';
import { checkResults, clickRuleName, submitQuery } from '../../tasks/live_query';
@@ -31,9 +32,8 @@ describe('Alert Test', { tags: ['@ess'] }, () => {
onBeforeLoad: (win) => disableNewFeaturesTours(win),
});
clickRuleName(ruleName);
- cy.getBySel('expand-event').first().click({ force: true });
-
- cy.wait(500);
+ waitForAlertsToPopulate();
+ cy.getBySel('expand-event').first().click();
cy.getBySel('securitySolutionFlyoutInvestigationGuideButton').click();
cy.contains('Get processes').click();
});
From 8d255b372dfd02a71166e9be4b7723d919b15680 Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 05:26:36 +1100
Subject: [PATCH 07/12] [8.16] [Dashboard] fix Export CSV doesnt work (#198547)
(#198582)
# Backport
This will backport the following commits from `main` to `8.16`:
- [[Dashboard] fix Export CSV doesnt work
(#198547)](https://github.com/elastic/kibana/pull/198547)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: Nathan Reese
---
src/plugins/dashboard/kibana.jsonc | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/dashboard/kibana.jsonc b/src/plugins/dashboard/kibana.jsonc
index 2bf60cde55ef0..77c2337d9944e 100644
--- a/src/plugins/dashboard/kibana.jsonc
+++ b/src/plugins/dashboard/kibana.jsonc
@@ -12,6 +12,7 @@
"dataViews",
"dataViewEditor",
"embeddable",
+ "fieldFormats",
"controls",
"inspector",
"navigation",
From 427ddb1e6b226315ddd7e57c09c5b82878b9fa2f Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 06:31:27 +1100
Subject: [PATCH 08/12] [8.16] [Docs] Update dashboard docs for interactive
managed dashboard popover (#198226) (#198607)
# Backport
This will backport the following commits from `main` to `8.16`:
- [[Docs] Update dashboard docs for interactive managed dashboard
popover (#198226)](https://github.com/elastic/kibana/pull/198226)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: wajihaparvez
---
.../user/dashboard/create-dashboards.asciidoc | 19 ++++++++++++++++++
docs/user/dashboard/dashboard.asciidoc | 2 +-
docs/user/dashboard/drilldowns.asciidoc | 2 +-
.../managed-dashboard-popover-8.16.0.png | Bin 0 -> 34533 bytes
4 files changed, 21 insertions(+), 2 deletions(-)
create mode 100644 docs/user/dashboard/images/managed-dashboard-popover-8.16.0.png
diff --git a/docs/user/dashboard/create-dashboards.asciidoc b/docs/user/dashboard/create-dashboards.asciidoc
index b07b4e88a684a..8b0d5e5f524fd 100644
--- a/docs/user/dashboard/create-dashboards.asciidoc
+++ b/docs/user/dashboard/create-dashboards.asciidoc
@@ -83,6 +83,7 @@ image::https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltf75cdb828
[[save-dashboards]]
. **Save** the dashboard. You can then leave the **Edit** mode and *Switch to view mode*.
+NOTE: Managed dashboards can't be edited directly, but you can <> them and edit these duplicates.
[[reset-the-dashboard]]
=== Reset dashboard changes
@@ -155,6 +156,24 @@ Copy panels from one dashboard to another dashboard.
[role="screenshot"]
image:https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt64206db263cf5514/66f49286833cffb09bebd18d/copy-to-dashboard-8.15.0.gif[Copy a panel to another dashboard, width 30%]
+[[duplicate-dashboards]]
+== Duplicate dashboards
+
+. Open the dashboard you want to duplicate.
+
+. In *View* mode, click *Duplicate* in the toolbar.
+
+. In the *Duplicate dashboard* window, enter a title and optional description and tags.
+
+. Click *Save*.
+
+You will be redirected to the duplicated dashboard.
+
+To duplicate a managed dashboard, follow the instructions above or click the *Managed* badge in the toolbar. Then click *Duplicate* in the dialogue that appears.
+
+[role="screenshot"]
+image::images/managed-dashboard-popover-8.16.0.png[Managed badge dialog with Duplicate button, width=40%]
+
== Import dashboards
You can import dashboards from the **Saved Objects** page under **Stack Management**. Refer to <>.
diff --git a/docs/user/dashboard/dashboard.asciidoc b/docs/user/dashboard/dashboard.asciidoc
index 5ca198c9831af..2bc6738516f15 100644
--- a/docs/user/dashboard/dashboard.asciidoc
+++ b/docs/user/dashboard/dashboard.asciidoc
@@ -17,7 +17,7 @@ There are several <> in {kib} that let you create
// add link to sharing section
At any time, you can <> you've created with your team, in {kib} or outside.
-Some dashboards are created and managed by the system, and are identified as `managed` in your list of of dashboards. This generally happens when you set up an integration to add data. You can't edit managed dashboards directly, but you can duplicate them and edit these duplicates.
+Some dashboards are created and managed by the system, and are identified as `managed` in your list of dashboards. This generally happens when you set up an integration to add data. You can't edit managed dashboards directly, but you can <> them and edit these duplicates.
--
diff --git a/docs/user/dashboard/drilldowns.asciidoc b/docs/user/dashboard/drilldowns.asciidoc
index 6b3a6d80ecdda..cb568d97e69ee 100644
--- a/docs/user/dashboard/drilldowns.asciidoc
+++ b/docs/user/dashboard/drilldowns.asciidoc
@@ -1,6 +1,6 @@
[role="xpack"]
[[drilldowns]]
-=== Drilldowns
+=== Add drilldowns
Panels have built-in interactive capabilities that apply filters to the dashboard data. For example, when you drag a time range or click a pie slice, a filter for the time range or pie slice is applied. Drilldowns let you customize the interactive behavior while keeping the context of the interaction.
diff --git a/docs/user/dashboard/images/managed-dashboard-popover-8.16.0.png b/docs/user/dashboard/images/managed-dashboard-popover-8.16.0.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1cd0562a42c70821db421af6b2989e653b17f9c
GIT binary patch
literal 34533
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%0A+redoSXCiH82cCJeuA
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
Ir18i92L_HOTmS$7
literal 0
HcmV?d00001
From 365c0a39973cc474e09c683861c6274cc68461c6 Mon Sep 17 00:00:00 2001
From: Cee Chen <549407+cee-chen@users.noreply.github.com>
Date: Thu, 31 Oct 2024 12:35:20 -0700
Subject: [PATCH 09/12] Upgrade EUI to v97.0.0-backport.1 (#198577)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`97.0.0-backport.0`⏩`97.0.0-backport.1`
This backport release addresses #197542 and
https://github.com/elastic/kibana/pull/197790#issuecomment-2443864669
---
##
[`v97.0.0-backport.1`](https://github.com/elastic/eui/releases/v97.0.0-backport.1)
**This is a backport release only intended for use by Kibana.**
**Bug fixes**
- Fixed `EuiSelectableTemplateSitewide`s within dark-themed `EuiHeader`s
missing input borders
([#8100](https://github.com/elastic/eui/pull/8100))
---
package.json | 2 +-
src/dev/license_checker/config.ts | 2 +-
yarn.lock | 46 ++++++-------------------------
3 files changed, 10 insertions(+), 40 deletions(-)
diff --git a/package.json b/package.json
index 2b7f9cfd87861..7720b030be546 100644
--- a/package.json
+++ b/package.json
@@ -119,7 +119,7 @@
"@elastic/ecs": "^8.11.1",
"@elastic/elasticsearch": "^8.15.0",
"@elastic/ems-client": "8.5.3",
- "@elastic/eui": "97.0.0-backport.0",
+ "@elastic/eui": "97.0.0-backport.1",
"@elastic/filesaver": "1.1.2",
"@elastic/node-crypto": "^1.2.3",
"@elastic/numeral": "^2.5.1",
diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts
index 59bf71885474c..02fbb94974ffa 100644
--- a/src/dev/license_checker/config.ts
+++ b/src/dev/license_checker/config.ts
@@ -87,7 +87,7 @@ 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@8.5.3': ['Elastic License 2.0'],
- '@elastic/eui@97.0.0-backport.0': ['Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0'],
+ '@elastic/eui@97.0.0-backport.1': ['Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0'],
'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry
'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary
'@bufbuild/protobuf@1.2.1': ['Apache-2.0'], // license (Apache-2.0 AND BSD-3-Clause)
diff --git a/yarn.lock b/yarn.lock
index 379a5c9261271..46f953a50a7dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1753,10 +1753,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@97.0.0-backport.0":
- version "97.0.0-backport.0"
- resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-97.0.0-backport.0.tgz#cababac6e5937b14ce0e836240fc4817e2e41920"
- integrity sha512-gefYh5ZgjFraGWOTy8f8RO5DAfOJB3S/PAlM9dvi6mNlNJ5T1CelNafBwdrD8Hdut//BxmexQD7aBZ+36GTaOg==
+"@elastic/eui@97.0.0-backport.1":
+ version "97.0.0-backport.1"
+ resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-97.0.0-backport.1.tgz#2f4c9e6edca3501b0178d2e98a7f6a8b07dc0d81"
+ integrity sha512-fv/R7c+CGIMeebQxMxScxiWBfOF/2PGgsdFwuj4zvPsLjGwGLFKzojOtykQDnSzGuIx4mxIJ+KVasWg8zl2Uig==
dependencies:
"@hello-pangea/dnd" "^16.6.0"
"@types/lodash" "^4.14.202"
@@ -29683,7 +29683,7 @@ string-replace-loader@^2.2.0:
loader-utils "^1.2.3"
schema-utils "^1.0.0"
-"string-width-cjs@npm:string-width@^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -29701,15 +29701,6 @@ string-width@^1.0.1:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
@@ -29820,7 +29811,7 @@ stringify-object@^3.2.1:
is-obj "^1.0.1"
is-regexp "^1.0.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -29834,13 +29825,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1:
dependencies:
ansi-regex "^2.0.0"
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.1, strip-ansi@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -32758,7 +32742,7 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -32784,15 +32768,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
@@ -32905,7 +32880,7 @@ xpath@^0.0.33:
resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.33.tgz#5136b6094227c5df92002e7c3a13516a5074eb07"
integrity sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA==
-"xstate5@npm:xstate@^5.18.1":
+"xstate5@npm:xstate@^5.18.1", xstate@^5.18.1:
version "5.18.1"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.18.1.tgz#c4d43ceaba6e6c31705d36bd96e285de4be4f7f4"
integrity sha512-m02IqcCQbaE/kBQLunwub/5i8epvkD2mFutnL17Oeg1eXTShe1sRF4D5mhv1dlaFO4vbW5gRGRhraeAD5c938g==
@@ -32915,11 +32890,6 @@ xstate@^4.38.2:
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.38.2.tgz#1b74544fc9c8c6c713ba77f81c6017e65aa89804"
integrity sha512-Fba/DwEPDLneHT3tbJ9F3zafbQXszOlyCJyQqqdzmtlY/cwE2th462KK48yaANf98jHlP6lJvxfNtN0LFKXPQg==
-xstate@^5.18.1:
- version "5.18.1"
- resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.18.1.tgz#c4d43ceaba6e6c31705d36bd96e285de4be4f7f4"
- integrity sha512-m02IqcCQbaE/kBQLunwub/5i8epvkD2mFutnL17Oeg1eXTShe1sRF4D5mhv1dlaFO4vbW5gRGRhraeAD5c938g==
-
"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
From 049ac4cb2ea7edad1be99b020a0d4c84d47148f4 Mon Sep 17 00:00:00 2001
From: mohamedhamed-ahmed
Date: Thu, 31 Oct 2024 20:20:50 +0000
Subject: [PATCH 10/12] [8.16] [Stream] Fix callout privileges (#198030)
(#198269)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
# Backport
This will backport the following commits from `main` to `8.16`:
- [[Stream] Fix callout privileges
(#198030)](https://github.com/elastic/kibana/pull/198030)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
.../infra/public/apps/logs_app.tsx | 31 +++-
.../components/logs_deprecation_callout.tsx | 42 ++++-
.../infra/public/plugin.ts | 155 ++++++++++--------
3 files changed, 144 insertions(+), 84 deletions(-)
diff --git a/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx b/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx
index 329e059288e3e..9d5583b0ecf4c 100644
--- a/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx
+++ b/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx
@@ -6,13 +6,19 @@
*/
import { History } from 'history';
-import { CoreStart } from '@kbn/core/public';
-import React from 'react';
+import { AppStatus, CoreStart } from '@kbn/core/public';
+import React, { useMemo } from 'react';
import ReactDOM from 'react-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { AppMountParameters } from '@kbn/core/public';
import { Storage } from '@kbn/kibana-utils-plugin/public';
-import { AllDatasetsLocatorParams, ALL_DATASETS_LOCATOR_ID } from '@kbn/deeplinks-observability';
+import {
+ AllDatasetsLocatorParams,
+ ALL_DATASETS_LOCATOR_ID,
+ OBSERVABILITY_LOGS_EXPLORER_APP_ID,
+} from '@kbn/deeplinks-observability';
+import useObservable from 'react-use/lib/useObservable';
+import { map } from 'rxjs';
import { LinkToLogsPage } from '../pages/link_to/link_to_logs';
import { LogsPage } from '../pages/logs';
import { InfraClientStartDeps, InfraClientStartExports } from '../types';
@@ -57,7 +63,22 @@ const LogsApp: React.FC<{
storage: Storage;
theme$: AppMountParameters['theme$'];
}> = ({ core, history, pluginStart, plugins, setHeaderActionMenu, storage, theme$ }) => {
- const { logs, discover, fleet } = core.application.capabilities;
+ const { logs } = core.application.capabilities;
+
+ const isLogsExplorerAppAccessible = useObservable(
+ useMemo(
+ () =>
+ core.application.applications$.pipe(
+ map(
+ (apps) =>
+ (apps.get(OBSERVABILITY_LOGS_EXPLORER_APP_ID)?.status ?? AppStatus.inaccessible) ===
+ AppStatus.accessible
+ )
+ ),
+ [core.application.applications$]
+ ),
+ false
+ );
return (
@@ -74,7 +95,7 @@ const LogsApp: React.FC<{
toastsService={core.notifications.toasts}
>
- {Boolean(discover?.show && fleet?.read) && (
+ {isLogsExplorerAppAccessible && (
{
const {
- services: { share },
+ services: { share, application },
} = useKibanaContextForPlugin();
+ const isLogsExplorerAppAccessible = useObservable(
+ useMemo(
+ () =>
+ application.applications$.pipe(
+ map(
+ (apps) =>
+ (apps.get(OBSERVABILITY_LOGS_EXPLORER_APP_ID)?.status ?? AppStatus.inaccessible) ===
+ AppStatus.accessible
+ )
+ ),
+ [application.applications$]
+ ),
+ false
+ );
+
const { dismissalStorageKey, message } = pageConfigurations[page];
const [isDismissed, setDismissed] = useLocalStorage(dismissalStorageKey, false);
- if (isDismissed) {
+ if (isDismissed || !isLogsExplorerAppAccessible) {
return null;
}
+ const allDatasetLocator =
+ share.url.locators.get(ALL_DATASETS_LOCATOR_ID);
+
return (
fill
data-test-subj="infraLogsDeprecationCalloutTryLogsExplorerButton"
color="warning"
- {...getLogsExplorerLinkProps(share)}
+ {...getLogsExplorerLinkProps(allDatasetLocator!)}
>
{i18n.translate('xpack.infra.logsDeprecationCallout.tryLogsExplorerButtonLabel', {
defaultMessage: 'Try Logs Explorer',
@@ -81,9 +107,7 @@ export const LogsDeprecationCallout = ({ page }: LogsDeprecationCalloutProps) =>
);
};
-const getLogsExplorerLinkProps = (share: SharePublicStart) => {
- const locator = share.url.locators.get(ALL_DATASETS_LOCATOR_ID)!;
-
+const getLogsExplorerLinkProps = (locator: LocatorPublic) => {
return getRouterLinkProps({
href: locator.getRedirectUrl({}),
onClick: () => locator.navigate({}),
diff --git a/x-pack/plugins/observability_solution/infra/public/plugin.ts b/x-pack/plugins/observability_solution/infra/public/plugin.ts
index daaa3510e1660..7b32df012a192 100644
--- a/x-pack/plugins/observability_solution/infra/public/plugin.ts
+++ b/x-pack/plugins/observability_solution/infra/public/plugin.ts
@@ -13,6 +13,8 @@ import {
DEFAULT_APP_CATEGORIES,
PluginInitializerContext,
AppDeepLinkLocations,
+ AppStatus,
+ ApplicationStart,
} from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
import { enableInfrastructureHostsView } from '@kbn/observability-plugin/public';
@@ -21,7 +23,7 @@ import {
MetricsExplorerLocatorParams,
ObservabilityTriggerId,
} from '@kbn/observability-shared-plugin/common';
-import { BehaviorSubject, combineLatest, from } from 'rxjs';
+import { BehaviorSubject, combineLatest, distinctUntilChanged, from, of, switchMap } from 'rxjs';
import { map } from 'rxjs';
import type { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { apiCanAddNewPanel } from '@kbn/presentation-containers';
@@ -35,6 +37,7 @@ import {
} from '@kbn/observability-shared-plugin/common';
import { OBSERVABILITY_ENABLE_LOGS_STREAM } from '@kbn/management-settings-ids';
import { NavigationEntry } from '@kbn/observability-shared-plugin/public';
+import { OBSERVABILITY_LOGS_EXPLORER_APP_ID } from '@kbn/deeplinks-observability/constants';
import type { InfraPublicConfig } from '../common/plugin_config_types';
import { createInventoryMetricRuleType } from './alerting/inventory';
import { createLogThresholdRuleType } from './alerting/log_threshold';
@@ -131,76 +134,75 @@ export class Plugin implements InfraClientPluginClass {
messageFields: this.config.sources?.default?.fields?.message,
});
- const startDep$AndHostViewFlag$ = combineLatest([
+ const startDep$AndAccessibleFlag$ = combineLatest([
from(core.getStartServices()),
core.settings.client.get$(enableInfrastructureHostsView),
- ]);
+ ]).pipe(
+ switchMap(([[{ application }], isInfrastructureHostsViewEnabled]) =>
+ combineLatest([
+ of(application),
+ of(isInfrastructureHostsViewEnabled),
+ getLogsExplorerAccessible$(application),
+ ])
+ )
+ );
const logRoutes = getLogsAppRoutes({ isLogsStreamEnabled });
/** !! Need to be kept in sync with the deepLinks in x-pack/plugins/observability_solution/infra/public/plugin.ts */
pluginsSetup.observabilityShared.navigation.registerSections(
- startDep$AndHostViewFlag$.pipe(
- map(
- ([
- [
- {
- application: { capabilities },
- },
- ],
- isInfrastructureHostsViewEnabled,
- ]) => {
- const { infrastructure, logs } = capabilities;
- return [
- ...(logs.show
- ? [
- {
- label: logsTitle,
- sortKey: 200,
- entries: getLogsNavigationEntries({
- capabilities,
- config: this.config,
- routes: logRoutes,
- }),
- },
- ]
- : []),
- ...(infrastructure.show
- ? [
- {
- label: metricsTitle,
- sortKey: 300,
- entries: [
- {
- label: inventoryTitle,
- app: 'metrics',
- path: '/inventory',
- },
- ...(this.config.featureFlags.metricsExplorerEnabled
- ? [
- {
- label: metricsExplorerTitle,
- app: 'metrics',
- path: '/explorer',
- },
- ]
- : []),
- ...(isInfrastructureHostsViewEnabled
- ? [
- {
- label: hostsTitle,
- app: 'metrics',
- path: '/hosts',
- },
- ]
- : []),
- ],
- },
- ]
- : []),
- ];
- }
- )
+ startDep$AndAccessibleFlag$.pipe(
+ map(([application, isInfrastructureHostsViewEnabled, isLogsExplorerAccessible]) => {
+ const { infrastructure, logs } = application.capabilities;
+ return [
+ ...(logs.show
+ ? [
+ {
+ label: logsTitle,
+ sortKey: 200,
+ entries: getLogsNavigationEntries({
+ isLogsExplorerAccessible,
+ config: this.config,
+ routes: logRoutes,
+ }),
+ },
+ ]
+ : []),
+ ...(infrastructure.show
+ ? [
+ {
+ label: metricsTitle,
+ sortKey: 300,
+ entries: [
+ {
+ label: inventoryTitle,
+ app: 'metrics',
+ path: '/inventory',
+ },
+ ...(this.config.featureFlags.metricsExplorerEnabled
+ ? [
+ {
+ label: metricsExplorerTitle,
+ app: 'metrics',
+ path: '/explorer',
+ },
+ ]
+ : []),
+ ...(isInfrastructureHostsViewEnabled
+ ? [
+ {
+ label: hostsTitle,
+ app: 'metrics',
+ path: '/hosts',
+ },
+ ]
+ : []),
+ ],
+ },
+ ]
+ : []),
+ ];
+ })
)
);
@@ -333,9 +335,10 @@ export class Plugin implements InfraClientPluginClass {
},
});
- startDep$AndHostViewFlag$.subscribe(
- ([_startServices, isInfrastructureHostsViewEnabled]: [
- [CoreStart, InfraClientStartDeps, InfraClientStartExports],
+ startDep$AndAccessibleFlag$.subscribe(
+ ([_startServices, isInfrastructureHostsViewEnabled, _isLogsExplorerAccessible]: [
+ ApplicationStart,
+ boolean,
boolean
]) => {
this.appUpdater$.next(() => ({
@@ -408,11 +411,11 @@ export class Plugin implements InfraClientPluginClass {
}
const getLogsNavigationEntries = ({
- capabilities,
+ isLogsExplorerAccessible,
config,
routes,
}: {
- capabilities: CoreStart['application']['capabilities'];
+ isLogsExplorerAccessible: boolean;
config: InfraPublicConfig;
routes: LogsAppRoutes;
}) => {
@@ -420,7 +423,7 @@ const getLogsNavigationEntries = ({
if (!config.featureFlags.logsUIEnabled) return entries;
- if (capabilities.discover?.show && capabilities.fleet?.read) {
+ if (isLogsExplorerAccessible) {
entries.push({
label: 'Explorer',
app: 'observability-logs-explorer',
@@ -440,6 +443,18 @@ const getLogsNavigationEntries = ({
return entries;
};
+const getLogsExplorerAccessible$ = (application: CoreStart['application']) => {
+ const { applications$ } = application;
+ return applications$.pipe(
+ map(
+ (apps) =>
+ (apps.get(OBSERVABILITY_LOGS_EXPLORER_APP_ID)?.status ?? AppStatus.inaccessible) ===
+ AppStatus.accessible
+ ),
+ distinctUntilChanged()
+ );
+};
+
const createNavEntryFromRoute = ({ path, title }: LogsRoute): NavigationEntry => ({
app: 'logs',
label: title,
From 0e3ac4798e55033c4b17f3e0624160091a96da3d Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 07:37:48 +1100
Subject: [PATCH 11/12] [8.16] Fix broken documentation links in the App Search
plugin (#198572) (#198604)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
# Backport
This will backport the following commits from `main` to `8.16`:
- [Fix broken documentation links in the App Search plugin
(#198572)](https://github.com/elastic/kibana/pull/198572)
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
Co-authored-by: Aurélien FOUCRET
---
.../api_logs/components/empty_state.tsx | 4 ++--
.../crawler/components/crawl_rules_table.tsx | 4 ++--
.../deduplication_panel.tsx | 4 ++--
.../crawler/components/entry_points_table.tsx | 4 ++--
.../automatic_crawl_scheduler.tsx | 4 ++--
.../components/crawler/crawler_overview.tsx | 6 ++---
.../components/credentials/constants.ts | 4 ----
.../form_components/key_type.tsx | 6 +++--
.../credentials_list/credentials_list.tsx | 4 ++--
.../curations/components/empty_state.tsx | 4 ++--
.../api_code_example.tsx | 6 ++---
.../document_creation_buttons.tsx | 5 ++--
.../documents/components/empty_state.tsx | 4 ++--
.../engine_overview/engine_overview_empty.tsx | 4 ++--
.../components/empty_meta_engines_state.tsx | 4 ++--
.../meta_engine_creation/constants.tsx | 4 ++--
.../components/empty_state.tsx | 4 ++--
.../precision_slider/precision_slider.tsx | 8 +++++--
.../relevance_tuning_callouts.tsx | 5 ++--
.../components/empty_state.tsx | 4 ++--
.../role_mappings/role_mappings.tsx | 6 ++---
.../schema/components/empty_state.tsx | 9 +++++--
.../search_ui/components/empty_state.tsx | 4 ++--
.../components/search_ui/search_ui.tsx | 4 ++--
.../log_retention/log_retention_panel.tsx | 4 ++--
.../synonyms/components/empty_state.tsx | 4 ++--
.../public/applications/app_search/routes.ts | 24 -------------------
27 files changed, 66 insertions(+), 81 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx
index c78bf3e918737..bf8cf009759d0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx
@@ -11,7 +11,7 @@ import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { API_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.empty.buttonLabel', {
defaultMessage: 'View the API reference',
})}
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 bef8ed4462fdc..2f66dc455442e 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
@@ -23,11 +23,11 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
+import { docLinks } from '../../../../shared/doc_links';
import { clearFlashMessages, flashSuccessToast } from '../../../../shared/flash_messages';
import { GenericEndpointInlineEditableTable } from '../../../../shared/tables/generic_endpoint_inline_editable_table';
import { InlineEditableTableColumn } from '../../../../shared/tables/inline_editable_table/types';
import { ItemWithAnID } from '../../../../shared/tables/types';
-import { CRAWL_RULES_DOCS_URL } from '../../../routes';
import { CrawlerSingleDomainLogic } from '../crawler_single_domain_logic';
import {
CrawlerPolicies,
@@ -53,7 +53,7 @@ const DEFAULT_DESCRIPTION = (
defaultMessage="Create a crawl rule to include or exclude pages whose URL matches the rule. Rules run in sequential order, and each URL is evaluated according to the first match. {link}"
values={{
link: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.crawlRulesTable.descriptionLinkText',
{ defaultMessage: 'Learn more about crawl rules' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx
index 26794d0421353..ef4d7448a5785 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx
@@ -27,7 +27,7 @@ import { EuiSelectableLIOption } from '@elastic/eui/src/components/selectable/se
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { DUPLICATE_DOCS_URL } from '../../../../routes';
+import { docLinks } from '../../../../../shared/doc_links';
import { DataPanel } from '../../../data_panel';
import { CrawlerSingleDomainLogic } from '../../crawler_single_domain_logic';
@@ -84,7 +84,7 @@ export const DeduplicationPanel: React.FC = () => {
documents on this domain. {documentationLink}."
values={{
documentationLink: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.deduplicationPanel.learnMoreMessage',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx
index 4fc7a0569ba0e..d4bfdf77704b8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx
@@ -14,10 +14,10 @@ import { EuiFieldText, EuiLink, EuiSpacer, EuiText, EuiTitle } from '@elastic/eu
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
+import { docLinks } from '../../../../shared/doc_links';
import { GenericEndpointInlineEditableTable } from '../../../../shared/tables/generic_endpoint_inline_editable_table';
import { InlineEditableTableColumn } from '../../../../shared/tables/inline_editable_table/types';
import { ItemWithAnID } from '../../../../shared/tables/types';
-import { ENTRY_POINTS_DOCS_URL } from '../../../routes';
import { CrawlerDomain, EntryPoint } from '../types';
import { EntryPointsTableLogic } from './entry_points_table_logic';
@@ -80,7 +80,7 @@ export const EntryPointsTable: React.FC = ({
defaultMessage:
'Include the most important URLs for your website here. Entry point URLs will be the first pages to be indexed and processed for links to other pages.',
})}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.learnMoreLinkText',
{ defaultMessage: 'Learn more about entry points.' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx
index 4533ca04c75bc..cb0377a471b93 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx
@@ -36,8 +36,8 @@ import {
MONTHS_UNIT_LABEL,
WEEKS_UNIT_LABEL,
} from '../../../../../shared/constants/units';
+import { docLinks } from '../../../../../shared/doc_links';
-import { WEB_CRAWLER_DOCS_URL } from '../../../../routes';
import { CrawlUnits } from '../../types';
import { AutomaticCrawlSchedulerLogic } from './automatic_crawl_scheduler_logic';
@@ -81,7 +81,7 @@ export const AutomaticCrawlScheduler: React.FC = () => {
defaultMessage="Don't worry about it, we'll start a crawl for you. {readMoreMessage}."
values={{
readMoreMessage: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.automaticCrawlSchedule.readMoreLink',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx
index 13a13c25a5ad8..d18f40c4c9f23 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx
@@ -13,7 +13,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer, EuiText, EuiTitle } from
import { i18n } from '@kbn/i18n';
-import { WEB_CRAWLER_DOCS_URL, WEB_CRAWLER_LOG_DOCS_URL } from '../../routes';
+import { docLinks } from '../../../shared/doc_links';
import { getEngineBreadcrumbs } from '../engine';
import { AppSearchPageTemplate } from '../layout';
@@ -82,7 +82,7 @@ export const CrawlerOverview: React.FC = () => {
defaultMessage:
"Easily index your website's content. To get started, enter your domain name, provide optional entry points and crawl rules, and we will handle the rest.",
})}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.empty.crawlerDocumentationLinkDescription',
{
@@ -125,7 +125,7 @@ export const CrawlerOverview: React.FC = () => {
defaultMessage:
"Recent crawl requests are logged here. Using the request ID of each crawl, you can track progress and examine crawl events in Kibana's Discover or Logs user interfaces.",
})}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.configurationDocumentationLinkDescription',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
index 9676e7f859ac5..7468597294026 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
@@ -7,8 +7,6 @@
import { i18n } from '@kbn/i18n';
-import { AUTHENTICATION_DOCS_URL } from '../../routes';
-
export const CREDENTIALS_TITLE = i18n.translate(
'xpack.enterpriseSearch.appSearch.credentials.title',
{ defaultMessage: 'Credentials' }
@@ -108,5 +106,3 @@ export const TOKEN_TYPE_INFO = [
];
export const FLYOUT_ARIA_LABEL_ID = 'credentialsFlyoutTitle';
-
-export const DOCS_HREF = AUTHENTICATION_DOCS_URL;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx
index 2cf381d8f604f..5213f786dfead 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx
@@ -12,8 +12,10 @@ import { useValues, useActions } from 'kea';
import { EuiFormRow, EuiSelect, EuiText, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { docLinks } from '../../../../../shared/doc_links';
+
import { AppLogic } from '../../../../app_logic';
-import { TOKEN_TYPE_DESCRIPTION, TOKEN_TYPE_INFO, DOCS_HREF } from '../../constants';
+import { TOKEN_TYPE_DESCRIPTION, TOKEN_TYPE_INFO } from '../../constants';
import { CredentialsLogic } from '../../credentials_logic';
export const FormKeyType: React.FC = () => {
@@ -36,7 +38,7 @@ export const FormKeyType: React.FC = () => {
{tokenDescription}{' '}
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.credentials.documentationLink1', {
defaultMessage: 'Visit the documentation',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
index e351cdf36c657..4f45da9e26046 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
@@ -19,9 +19,9 @@ import {
import { i18n } from '@kbn/i18n';
import { EDIT_BUTTON_LABEL, DELETE_BUTTON_LABEL } from '../../../../shared/constants';
+import { docLinks } from '../../../../shared/doc_links';
import { HiddenText } from '../../../../shared/hidden_text';
import { convertMetaToPagination, handlePageChange } from '../../../../shared/table_pagination';
-import { API_KEYS_DOCS_URL } from '../../../routes';
import { TOKEN_TYPE_DISPLAY_NAMES } from '../constants';
import { CredentialsLogic } from '../credentials_logic';
import { ApiToken } from '../types';
@@ -141,7 +141,7 @@ export const CredentialsList: React.FC = () => {
defaultMessage: 'Allow applications to access Elastic App Search on your behalf.',
})}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.credentials.empty.buttonLabel', {
defaultMessage: 'Learn about API keys',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx
index 10d81f1623959..363da83d56aac 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { CURATIONS_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.curations.empty.buttonLabel', {
defaultMessage: 'Read the curations guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
index 7bbe276aedf69..98da6dc88ef57 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
@@ -30,8 +30,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { DocumentCreationLogic } from '..';
import { CANCEL_BUTTON_LABEL } from '../../../../shared/constants';
+import { docLinks } from '../../../../shared/doc_links';
import { getEnterpriseSearchUrl } from '../../../../shared/enterprise_search_url';
-import { API_CLIENTS_DOCS_URL, INDEXING_DOCS_URL } from '../../../routes';
import { EngineLogic } from '../../engine';
import { EngineDetails } from '../../engine/types';
@@ -74,12 +74,12 @@ export const FlyoutBody: React.FC = () => {
defaultMessage="The {documentsApiLink} can be used to add new documents to your engine, update documents, retrieve documents by id, and delete documents. There are a variety of {clientLibrariesLink} to help you get started."
values={{
documentsApiLink: (
-
+
documents API
),
clientLibrariesLink: (
-
+
client libraries
),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
index 07de7b3ec0c34..80e087e007671 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
@@ -26,9 +26,10 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { docLinks } from '../../../shared/doc_links';
import { parseQueryParams } from '../../../shared/query_params';
import { EuiCardTo } from '../../../shared/react_router_helpers';
-import { INDEXING_DOCS_URL, ENGINE_CRAWLER_PATH } from '../../routes';
+import { ENGINE_CRAWLER_PATH } from '../../routes';
import { generateEnginePath } from '../engine';
import illustration from './illustration.svg';
@@ -106,7 +107,7 @@ export const DocumentCreationButtons: React.FC = ({
)}
{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.documentCreation.buttons.emptyStateFooterLink',
{ defaultMessage: 'Read documentation' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx
index 85e834b320751..a311899d380e9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { INDEXING_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyState = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.documents.empty.buttonLabel', {
defaultMessage: 'Read the documents guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
index e31a17406ffd3..e4bcf810d58f8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
@@ -12,8 +12,8 @@ import { useValues } from 'kea';
import { EuiButton, EuiEmptyPrompt, EuiImage, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { docLinks } from '../../../shared/doc_links';
import { EuiButtonTo } from '../../../shared/react_router_helpers';
-import { DOCS_URL } from '../../routes';
import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation';
import illustration from '../document_creation/illustration.svg';
@@ -85,7 +85,7 @@ export const EmptyEngineOverview: React.FC = () => {
{ defaultMessage: 'Engine setup' }
),
rightSideItems: [
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.overview.empty.headingAction',
{ defaultMessage: 'View documentation' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx
index 3cf461e3f7d45..0824997ba8896 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { META_ENGINES_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyMetaEnginesState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engines.metaEngines.emptyPromptButtonLabel',
{ defaultMessage: 'Learn more about meta engines' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx
index e30868beeb209..8b32ffe77e701 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx
@@ -11,7 +11,7 @@ import { EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { META_ENGINES_DOCS_URL } from '../../routes';
+import { docLinks } from '../../../shared/doc_links';
export const DEFAULT_LANGUAGE = 'Universal';
@@ -57,7 +57,7 @@ export const META_ENGINE_CREATION_FORM_DOCUMENTATION_DESCRIPTION = (
defaultMessage="{documentationLink} for information about how to get started."
values={{
documentationLink: (
-
+
{META_ENGINE_CREATION_FORM_DOCUMENTATION_LINK}
),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx
index f17f7a582efdf..b792dec2cba0e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { RELEVANCE_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyState: React.FC = () => (
(
}
)}
actions={
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.buttonLabel',
{ defaultMessage: 'Read the relevance tuning guide' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
index e4b2027aa3d6d..d78949d0fbe74 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
@@ -21,7 +21,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { PRECISION_DOCS_URL } from '../../../../routes';
+import { docLinks } from '../../../../../shared/doc_links';
import { RelevanceTuningLogic } from '../../relevance_tuning_logic';
import { STEP_DESCRIPTIONS } from './constants';
@@ -57,7 +57,11 @@ export const PrecisionSlider: React.FC = () => {
defaultMessage: 'Fine tune the precision vs. recall settings on your engine.',
}
)}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.precisionSlider.learnMore.link',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx
index bf2c21a1003f5..ef0bea39439c5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx
@@ -13,8 +13,9 @@ import { EuiCallOut, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
+import { docLinks } from '../../../shared/doc_links';
import { EuiLinkTo } from '../../../shared/react_router_helpers';
-import { META_ENGINES_DOCS_URL, ENGINE_SCHEMA_PATH } from '../../routes';
+import { ENGINE_SCHEMA_PATH } from '../../routes';
import { EngineLogic, generateEnginePath } from '../engine';
import { RelevanceTuningLogic } from '.';
@@ -98,7 +99,7 @@ export const RelevanceTuningCallouts: React.FC = () => {
values={{
schemaFieldsWithConflictsCount,
link: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.whatsThisLinkLabel',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx
index 7f91447b910b6..6434a877ead5e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { RESULT_SETTINGS_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyState: React.FC = () => (
(
}
)}
actions={
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.buttonLabel',
{ defaultMessage: 'Read the result settings guide' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx
index aff138b9c3884..2ffe6cb357e54 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx
@@ -12,6 +12,7 @@ import { useActions, useValues } from 'kea';
import { EuiSpacer } from '@elastic/eui';
import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
+import { docLinks } from '../../../shared/doc_links';
import {
RoleMappingsTable,
RoleMappingsHeading,
@@ -22,7 +23,6 @@ import {
} from '../../../shared/role_mapping';
import { ROLE_MAPPINGS_TITLE } from '../../../shared/role_mapping/constants';
-import { SECURITY_DOCS_URL } from '../../routes';
import { AppSearchPageTemplate } from '../layout';
import { ROLE_MAPPINGS_ENGINE_ACCESS_HEADING } from './constants';
@@ -57,7 +57,7 @@ export const RoleMappings: React.FC = () => {
const rolesEmptyState = (
);
@@ -66,7 +66,7 @@ export const RoleMappings: React.FC = () => {
initializeRoleMapping()}
/>
{
@@ -40,7 +40,12 @@ export const EmptyState: React.FC = () => {
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.schema.empty.buttonLabel', {
defaultMessage: 'Read the indexing schema guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx
index 9a663e1372211..e5b0f2facedbd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { SEARCH_UI_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
export const EmptyState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.searchUI.empty.buttonLabel', {
defaultMessage: 'Read the Search UI guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx
index d7398357a5e58..cfef71d34fb9f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx
@@ -12,7 +12,7 @@ import { useActions, useValues } from 'kea';
import { EuiText, EuiFlexItem, EuiFlexGroup, EuiSpacer, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
-import { SEARCH_UI_DOCS_URL } from '../../routes';
+import { docLinks } from '../../../shared/doc_links';
import { EngineLogic, getEngineBreadcrumbs } from '../engine';
import { AppSearchPageTemplate } from '../layout';
@@ -63,7 +63,7 @@ export const SearchUI: React.FC = () => {
defaultMessage="Use the fields below to generate a sample search experience built with Search UI. Use the sample to preview search results, or build upon it to create your own custom search experience. {link}."
values={{
link: (
-
+
{
defaultMessage: 'Log retention is determined by the ILM policies for your deployment.',
})}
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.settings.logRetention.learnMore', {
defaultMessage: 'Learn more about log retention for Enterprise Search.',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx
index ef5e1dafa443f..ff7e8ce16c6d2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { SYNONYMS_DOCS_URL } from '../../../routes';
+import { docLinks } from '../../../../shared/doc_links';
import { SynonymModal, SynonymIcon } from '.';
@@ -35,7 +35,7 @@ export const EmptyState: React.FC = () => {
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.synonyms.empty.buttonLabel', {
defaultMessage: 'Read the synonyms guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
index 1a41004c882e3..128af5adacfad 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
@@ -5,30 +5,6 @@
* 2.0.
*/
-import { docLinks } from '../shared/doc_links';
-
-export const API_DOCS_URL = docLinks.appSearchApis;
-export const API_CLIENTS_DOCS_URL = docLinks.appSearchApiClients;
-export const API_KEYS_DOCS_URL = docLinks.appSearchApiKeys;
-export const AUTHENTICATION_DOCS_URL = docLinks.appSearchAuthentication;
-export const CRAWL_RULES_DOCS_URL = docLinks.appSearchCrawlRules;
-export const CURATIONS_DOCS_URL = docLinks.appSearchCurations;
-export const DOCS_URL = docLinks.appSearchGuide;
-export const DUPLICATE_DOCS_URL = docLinks.appSearchDuplicateDocuments;
-export const ENTRY_POINTS_DOCS_URL = docLinks.appSearchEntryPoints;
-export const INDEXING_DOCS_URL = docLinks.appSearchIndexingDocs;
-export const INDEXING_SCHEMA_DOCS_URL = docLinks.appSearchIndexingDocsSchema;
-export const LOG_SETTINGS_DOCS_URL = docLinks.appSearchLogSettings;
-export const META_ENGINES_DOCS_URL = docLinks.appSearchMetaEngines;
-export const PRECISION_DOCS_URL = docLinks.appSearchPrecision;
-export const RELEVANCE_DOCS_URL = docLinks.appSearchRelevance;
-export const RESULT_SETTINGS_DOCS_URL = docLinks.appSearchResultSettings;
-export const SEARCH_UI_DOCS_URL = docLinks.appSearchSearchUI;
-export const SECURITY_DOCS_URL = docLinks.appSearchSecurity;
-export const SYNONYMS_DOCS_URL = docLinks.appSearchSynonyms;
-export const WEB_CRAWLER_DOCS_URL = docLinks.appSearchWebCrawler;
-export const WEB_CRAWLER_LOG_DOCS_URL = docLinks.appSearchWebCrawlerEventLogs;
-
export const ROOT_PATH = '/';
export const SETUP_GUIDE_PATH = '/setup_guide';
export const LIBRARY_PATH = '/library';
From 931579bab901ea005108e9871f730344723ec10d Mon Sep 17 00:00:00 2001
From: Tiago Vila Verde
Date: Thu, 31 Oct 2024 22:22:48 +0100
Subject: [PATCH 12/12] [8.16] Backport: [eem] rename fields to snake case
#195895 (#198501)
Backporting https://github.com/elastic/kibana/pull/195895 into 8.16.
---------
Co-authored-by: Kevin Lacabane
---
packages/kbn-apm-synthtrace-client/index.ts | 1 +
.../src/lib/entities/container_entity.ts | 42 +++++++++
.../src/lib/entities/host_entity.ts | 42 +++++++++
.../src/lib/entities/index.ts | 36 +++++++
.../src/lib/entities/service_entity.ts | 45 +++++++++
.../entities/entities_synthtrace_es_client.ts | 94 +++++++++++++++++++
.../src/rest_specs/entity.ts | 13 ++-
.../src/schema/entity.test.ts | 20 ++--
.../kbn-entities-schema/src/schema/entity.ts | 19 ++--
.../server/lib/auth/privileges.ts | 2 +-
.../built_in/services_from_ecs_data.ts | 4 +-
.../create_and_install_ingest_pipeline.ts | 2 +-
.../server/lib/entities/delete_index.ts | 6 +-
.../generate_latest_processors.test.ts.snap | 20 ++--
.../generate_latest_processors.ts | 10 +-
.../install_entity_definition.test.ts | 54 ++++++-----
.../lib/entities/install_entity_definition.ts | 64 +++++++------
.../generate_latest_transform.test.ts.snap | 4 +-
.../transform/generate_latest_transform.ts | 4 +-
.../lib/entities/upgrade_entity_definition.ts | 8 +-
.../server/lib/entity_client.ts | 32 +++++--
.../server/lib/manage_index_templates.ts | 6 --
.../entity_manager/server/lib/utils.ts | 8 +-
.../server/routes/enablement/check.ts | 4 +-
.../server/routes/enablement/disable.ts | 4 +-
.../server/routes/enablement/enable.ts | 8 +-
.../server/routes/entities/update.ts | 68 ++++----------
.../templates/components/base_history.ts | 36 -------
.../templates/components/base_latest.ts | 5 +-
.../server/templates/components/entity.ts | 10 +-
.../apm/server/routes/entities/types.ts | 5 +-
.../entities/utils/merge_entities.test.ts | 75 ++++++---------
.../routes/entities/utils/merge_entities.ts | 2 +-
...parse_identity_field_values_to_kql.test.ts | 10 +-
.../alerts_badge/alerts_badge.test.tsx | 24 ++---
.../entity_name/entity_name.test.tsx | 48 +++++-----
.../entities/get_identify_fields.test.ts | 6 +-
.../assistant_hypothesis.tsx | 2 +-
.../server/services/get_entities.ts | 26 ++---
.../common/field_names/elasticsearch.ts | 10 +-
.../elasticsearch_assets/ingest_pipeline.ts | 2 +-
.../remove_entity_definition_fields_step.ts | 13 ++-
.../apis/entity_manager/definitions.ts | 20 ----
.../entity_store/mappings.json | 26 ++---
44 files changed, 554 insertions(+), 386 deletions(-)
create mode 100644 packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts
create mode 100644 packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts
create mode 100644 packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts
create mode 100644 packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts
create mode 100644 packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts
delete mode 100644 x-pack/plugins/entity_manager/server/templates/components/base_history.ts
diff --git a/packages/kbn-apm-synthtrace-client/index.ts b/packages/kbn-apm-synthtrace-client/index.ts
index 6ac3b6525ec00..bdb93fbe20076 100644
--- a/packages/kbn-apm-synthtrace-client/index.ts
+++ b/packages/kbn-apm-synthtrace-client/index.ts
@@ -37,3 +37,4 @@ export type { ESDocumentWithOperation, SynthtraceESAction, SynthtraceGenerator }
export { log, type LogDocument, LONG_FIELD_NAME } from './src/lib/logs';
export { type AssetDocument } from './src/lib/assets';
export { syntheticsMonitor, type SyntheticsMonitorDocument } from './src/lib/synthetics';
+export { type EntityFields, entities } from './src/lib/entities';
diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts
new file mode 100644
index 0000000000000..d7f34d7e9e484
--- /dev/null
+++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts
@@ -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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { EntityDataStreamType, EntityFields } from '.';
+import { Serializable } from '../serializable';
+
+class ContainerEntity extends Serializable {
+ constructor(fields: EntityFields) {
+ super({
+ ...fields,
+ 'entity.type': 'container',
+ 'entity.definition_id': 'builtin_containers_from_ecs_data',
+ 'entity.identity_fields': ['container.id'],
+ });
+ }
+}
+
+export function containerEntity({
+ agentName,
+ dataStreamType,
+ containerId,
+ entityId,
+}: {
+ agentName: string[];
+ dataStreamType: EntityDataStreamType[];
+ containerId: string;
+ entityId: string;
+}) {
+ return new ContainerEntity({
+ 'source_data_stream.type': dataStreamType,
+ 'agent.name': agentName,
+ 'container.id': containerId,
+ 'entity.display_name': containerId,
+ 'entity.id': entityId,
+ });
+}
diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts
new file mode 100644
index 0000000000000..c2c0330bb03ca
--- /dev/null
+++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts
@@ -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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { EntityDataStreamType, EntityFields } from '.';
+import { Serializable } from '../serializable';
+
+class HostEntity extends Serializable {
+ constructor(fields: EntityFields) {
+ super({
+ ...fields,
+ 'entity.type': 'host',
+ 'entity.definition_id': 'builtin_hosts_from_ecs_data',
+ 'entity.identity_fields': ['host.name'],
+ });
+ }
+}
+
+export function hostEntity({
+ agentName,
+ dataStreamType,
+ hostName,
+ entityId,
+}: {
+ agentName: string[];
+ dataStreamType: EntityDataStreamType[];
+ hostName: string;
+ entityId: string;
+}) {
+ return new HostEntity({
+ 'source_data_stream.type': dataStreamType,
+ 'agent.name': agentName,
+ 'host.name': hostName,
+ 'entity.display_name': hostName,
+ 'entity.id': entityId,
+ });
+}
diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts
new file mode 100644
index 0000000000000..d791e9bdc6c34
--- /dev/null
+++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/index.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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { Fields } from '../entity';
+import { serviceEntity } from './service_entity';
+import { hostEntity } from './host_entity';
+import { containerEntity } from './container_entity';
+
+export type EntityDataStreamType = 'metrics' | 'logs' | 'traces';
+export type Schema = 'ecs' | 'semconv';
+
+export type EntityFields = Fields &
+ Partial<{
+ 'agent.name': string[];
+ 'source_data_stream.type': string | string[];
+ 'source_data_stream.dataset': string | string[];
+ 'event.ingested': string;
+ source_index: string;
+ 'entity.last_seen_timestamp': string;
+ 'entity.schema_version': string;
+ 'entity.definition_version': string;
+ 'entity.display_name': string;
+ 'entity.identity_fields': string | string[];
+ 'entity.id': string;
+ 'entity.type': string;
+ 'entity.definition_id': string;
+ [key: string]: any;
+ }>;
+
+export const entities = { serviceEntity, hostEntity, containerEntity };
diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts
new file mode 100644
index 0000000000000..e711f2dad223f
--- /dev/null
+++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { EntityDataStreamType, EntityFields } from '.';
+import { Serializable } from '../serializable';
+
+class ServiceEntity extends Serializable {
+ constructor(fields: EntityFields) {
+ super({
+ ...fields,
+ 'entity.type': 'service',
+ 'entity.definition_id': 'builtin_services_from_ecs_data',
+ 'entity.identity_fields': ['service.name'],
+ });
+ }
+}
+
+export function serviceEntity({
+ agentName,
+ dataStreamType,
+ serviceName,
+ environment,
+ entityId,
+}: {
+ agentName: string[];
+ serviceName: string;
+ dataStreamType: EntityDataStreamType[];
+ environment?: string;
+ entityId: string;
+}) {
+ return new ServiceEntity({
+ 'service.name': serviceName,
+ 'entity.display_name': serviceName,
+ 'service.environment': environment,
+ 'source_data_stream.type': dataStreamType,
+ 'agent.name': agentName,
+ 'entity.id': entityId,
+ });
+}
diff --git a/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts b/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts
new file mode 100644
index 0000000000000..4c5d17111fca6
--- /dev/null
+++ b/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts
@@ -0,0 +1,94 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { Client } from '@elastic/elasticsearch';
+import { EntityFields, ESDocumentWithOperation } from '@kbn/apm-synthtrace-client';
+import { pipeline, Readable, Transform } from 'stream';
+import { SynthtraceEsClient, SynthtraceEsClientOptions } from '../shared/base_client';
+import { getDedotTransform } from '../shared/get_dedot_transform';
+import { getSerializeTransform } from '../shared/get_serialize_transform';
+import { Logger } from '../utils/create_logger';
+
+export type EntitiesSynthtraceEsClientOptions = Omit;
+
+interface Pipeline {
+ includeSerialization?: boolean;
+}
+
+export class EntitiesSynthtraceEsClient extends SynthtraceEsClient {
+ constructor(options: { client: Client; logger: Logger } & EntitiesSynthtraceEsClientOptions) {
+ super({
+ ...options,
+ pipeline: entitiesPipeline(),
+ });
+ this.indices = ['.entities.v1.latest.builtin*'];
+ }
+
+ getDefaultPipeline({ includeSerialization }: Pipeline = { includeSerialization: true }) {
+ return entitiesPipeline({ includeSerialization });
+ }
+}
+
+function entitiesPipeline({ includeSerialization }: Pipeline = { includeSerialization: true }) {
+ return (base: Readable) => {
+ const serializationTransform = includeSerialization ? [getSerializeTransform()] : [];
+
+ return pipeline(
+ // @ts-expect-error Some weird stuff here with the type definition for pipeline. We have tests!
+ base,
+ ...serializationTransform,
+ lastSeenTimestampTransform(),
+ getRoutingTransform(),
+ getDedotTransform(),
+ (err: unknown) => {
+ if (err) {
+ throw err;
+ }
+ }
+ );
+ };
+}
+
+function lastSeenTimestampTransform() {
+ return new Transform({
+ objectMode: true,
+ transform(document: ESDocumentWithOperation, encoding, callback) {
+ const timestamp = document['@timestamp'];
+ if (timestamp) {
+ const isoString = new Date(timestamp).toISOString();
+ document['entity.last_seen_timestamp'] = isoString;
+ document['event.ingested'] = isoString;
+ delete document['@timestamp'];
+ }
+ callback(null, document);
+ },
+ });
+}
+
+function getRoutingTransform() {
+ return new Transform({
+ objectMode: true,
+ transform(document: ESDocumentWithOperation, encoding, callback) {
+ const entityType: string | undefined = document['entity.type'];
+ if (entityType === undefined) {
+ throw new Error(`entity.type was not defined: ${JSON.stringify(document)}`);
+ }
+ const entityIndexName = `${entityType}s`;
+ document._action = {
+ index: {
+ _index:
+ `.entities.v1.latest.builtin_${entityIndexName}_from_ecs_data`.toLocaleLowerCase(),
+ _id: document['entity.id'],
+ },
+ };
+
+ callback(null, document);
+ },
+ });
+}
diff --git a/packages/kbn-investigation-shared/src/rest_specs/entity.ts b/packages/kbn-investigation-shared/src/rest_specs/entity.ts
index 1c29192c2a098..8e571f3e2a4d4 100644
--- a/packages/kbn-investigation-shared/src/rest_specs/entity.ts
+++ b/packages/kbn-investigation-shared/src/rest_specs/entity.ts
@@ -19,13 +19,12 @@ const metricsSchema = z.object({
const entitySchema = z.object({
id: z.string(),
- definitionId: z.string(),
- definitionVersion: z.string(),
- displayName: z.string(),
- firstSeenTimestamp: z.string(),
- lastSeenTimestamp: z.string(),
- identityFields: z.array(z.string()),
- schemaVersion: z.string(),
+ definition_id: z.string(),
+ definition_version: z.string(),
+ display_name: z.string(),
+ last_seen_timestamp: z.string(),
+ identity_fields: z.array(z.string()),
+ schema_version: z.string(),
type: z.string(),
metrics: metricsSchema,
});
diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts
index c8ef716371338..000edeadbcf83 100644
--- a/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts
+++ b/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts
@@ -9,19 +9,15 @@ import { entityLatestSchema, entityMetadataSchema } from './entity';
const entity = {
entity: {
- lastSeenTimestamp: '2024-08-06T17:03:50.722Z',
- schemaVersion: 'v1',
- definitionVersion: '999.999.999',
- displayName: 'message_processor',
- identityFields: ['log.logger', 'event.category'],
+ last_seen_timestamp: '2024-08-06T17:03:50.722Z',
+ schema_version: 'v1',
+ definition_version: '999.999.999',
+ display_name: 'message_processor',
+ identity_fields: ['log.logger', 'event.category'],
id: '6UHVPiduEC2qk6rMjs1Jzg==',
- metrics: {
- logRate: 100,
- errorRate: 0,
- },
type: 'service',
- firstSeenTimestamp: '2024-08-06T16:50:00.000Z',
- definitionId: 'admin-console-services',
+ metrics: {},
+ definition_id: 'admin-console-services',
},
};
@@ -47,7 +43,7 @@ const metadata = {
ingested: '2024-08-06T17:06:24.444700Z',
category: '',
},
- sourceIndex: ['kbn-data-forge-fake_stack.message_processor-2024-08-01'],
+ source_index: ['kbn-data-forge-fake_stack.message_processor-2024-08-01'],
log: {
logger: 'message_processor',
},
diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts
index 3eb87a797ef21..9ab02e0931d9c 100644
--- a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts
+++ b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts
@@ -11,12 +11,12 @@ import { arrayOfStringsSchema } from './common';
export const entityBaseSchema = z.object({
id: z.string(),
type: z.string(),
- identityFields: arrayOfStringsSchema,
- displayName: z.string(),
+ identity_fields: arrayOfStringsSchema,
+ display_name: z.string(),
metrics: z.record(z.string(), z.number()),
- definitionVersion: z.string(),
- schemaVersion: z.string(),
- definitionId: z.string(),
+ definition_version: z.string(),
+ schema_version: z.string(),
+ definition_id: z.string(),
});
export interface MetadataRecord {
@@ -34,15 +34,8 @@ export const entityLatestSchema = z
.object({
entity: entityBaseSchema.merge(
z.object({
- lastSeenTimestamp: z.string(),
+ last_seen_timestamp: z.string(),
})
),
})
.and(entityMetadataSchema);
-
-export const entityHistorySchema = z
- .object({
- '@timestamp': z.string(),
- entity: entityBaseSchema,
- })
- .and(entityMetadataSchema);
diff --git a/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts b/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts
index 5ca3da77d7eba..674e870c898bc 100644
--- a/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts
+++ b/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts
@@ -59,7 +59,7 @@ export const entityDefinitionRuntimePrivileges = {
index: [
{
names: [ENTITY_INTERNAL_INDICES_PATTERN],
- privileges: ['create_index', 'index', 'create_doc', 'auto_configure', 'read'],
+ privileges: ['create_index', 'delete_index', 'index', 'create_doc', 'auto_configure', 'read'],
},
{
names: [...BUILT_IN_ALLOWED_INDICES, ENTITY_INTERNAL_INDICES_PATTERN],
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts b/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts
index d6aa4d08ad221..8be37435ca0cd 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts
@@ -29,7 +29,7 @@ export const builtInServicesFromEcsEntityDefinition: EntityDefinition =
identityFields: ['service.name'],
displayNameTemplate: '{{service.name}}',
metadata: [
- { source: '_index', destination: 'sourceIndex' },
+ { source: '_index', destination: 'source_index' },
{
source: 'data_stream.type',
destination: 'source_data_stream.type',
@@ -38,7 +38,7 @@ export const builtInServicesFromEcsEntityDefinition: EntityDefinition =
source: 'data_stream.dataset',
destination: 'source_data_stream.dataset',
},
- { source: 'agent.name', aggregation: { type: 'terms', limit: 100 } },
+ 'agent.name',
'service.environment',
'service.name',
'service.namespace',
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts b/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts
index 0b3900363c0c8..5511e50c36ab8 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts
@@ -25,7 +25,7 @@ export async function createAndInstallIngestPipelines(
id: latestId,
processors: latestProcessors,
_meta: {
- definitionVersion: definition.version,
+ definition_version: definition.version,
managed: definition.managed,
},
}),
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts b/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts
index d40d9975a8820..491cd08e6d48c 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts
@@ -14,11 +14,13 @@ export async function deleteIndices(
definition: EntityDefinition,
logger: Logger
) {
+ const index = generateLatestIndexName(definition);
try {
- const index = generateLatestIndexName(definition);
await esClient.indices.delete({ index, ignore_unavailable: true });
} catch (e) {
- logger.error(`Unable to remove entity definition index [${definition.id}}]`);
+ logger.error(
+ `Unable to remove entity definition index ${index} for definition [${definition.id}]`
+ );
throw e;
}
}
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap
index 37f600f3a271f..429b5fdce9309 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap
+++ b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap
@@ -16,25 +16,25 @@ Array [
},
Object {
"set": Object {
- "field": "entity.definitionId",
+ "field": "entity.definition_id",
"value": "builtin_mock_entity_definition",
},
},
Object {
"set": Object {
- "field": "entity.definitionVersion",
+ "field": "entity.definition_version",
"value": "1.0.0",
},
},
Object {
"set": Object {
- "field": "entity.schemaVersion",
+ "field": "entity.schema_version",
"value": "v1",
},
},
Object {
"set": Object {
- "field": "entity.identityFields",
+ "field": "entity.identity_fields",
"value": Array [
"log.logger",
],
@@ -92,7 +92,7 @@ if (ctx.entity?.metadata?.sourceIndex?.data != null) {
},
Object {
"set": Object {
- "field": "entity.displayName",
+ "field": "entity.display_name",
"value": "{{log.logger}}",
},
},
@@ -121,25 +121,25 @@ Array [
},
Object {
"set": Object {
- "field": "entity.definitionId",
+ "field": "entity.definition_id",
"value": "admin-console-services",
},
},
Object {
"set": Object {
- "field": "entity.definitionVersion",
+ "field": "entity.definition_version",
"value": "1.0.0",
},
},
Object {
"set": Object {
- "field": "entity.schemaVersion",
+ "field": "entity.schema_version",
"value": "v1",
},
},
Object {
"set": Object {
- "field": "entity.identityFields",
+ "field": "entity.identity_fields",
"value": Array [
"log.logger",
],
@@ -197,7 +197,7 @@ if (ctx.entity?.metadata?.sourceIndex?.data != null) {
},
Object {
"set": Object {
- "field": "entity.displayName",
+ "field": "entity.display_name",
"value": "{{log.logger}}",
},
},
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts
index 787633246dede..335c135448b10 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts
@@ -117,25 +117,25 @@ export function generateLatestProcessors(definition: EntityDefinition) {
},
{
set: {
- field: 'entity.definitionId',
+ field: 'entity.definition_id',
value: definition.id,
},
},
{
set: {
- field: 'entity.definitionVersion',
+ field: 'entity.definition_version',
value: definition.version,
},
},
{
set: {
- field: 'entity.schemaVersion',
+ field: 'entity.schema_version',
value: ENTITY_SCHEMA_VERSION_V1,
},
},
{
set: {
- field: 'entity.identityFields',
+ field: 'entity.identity_fields',
value: definition.identityFields.map((identityField) => identityField.field),
},
},
@@ -173,7 +173,7 @@ export function generateLatestProcessors(definition: EntityDefinition) {
// This must happen AFTER we lift the identity fields into the root of the document
{
set: {
- field: 'entity.displayName',
+ field: 'entity.display_name',
value: definition.displayNameTemplate,
},
},
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts
index e07670c58fd9b..4633885b51387 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts
@@ -74,7 +74,7 @@ const assertHasCreatedDefinition = (
id: generateLatestIngestPipelineId(definition),
processors: expect.anything(),
_meta: {
- definitionVersion: definition.version,
+ definition_version: definition.version,
managed: definition.managed,
},
});
@@ -112,7 +112,7 @@ const assertHasUpgradedDefinition = (
id: generateLatestIngestPipelineId(definition),
processors: expect.anything(),
_meta: {
- definitionVersion: definition.version,
+ definition_version: definition.version,
managed: definition.managed,
},
});
@@ -260,7 +260,7 @@ describe('install_entity_definition', () => {
describe('installBuiltInEntityDefinitions', () => {
it('should install definition when not found', async () => {
const builtInDefinitions = [mockEntityDefinition];
- const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
+ const clusterClient = elasticsearchClientMock.createScopedClusterClient();
const soClient = savedObjectsClientMock.create();
soClient.find.mockResolvedValue({ saved_objects: [], total: 0, page: 1, per_page: 10 });
soClient.update.mockResolvedValue({
@@ -271,18 +271,19 @@ describe('install_entity_definition', () => {
});
await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
definitions: builtInDefinitions,
logger: loggerMock.create(),
});
- assertHasCreatedDefinition(mockEntityDefinition, soClient, esClient);
+ assertHasCreatedDefinition(mockEntityDefinition, soClient, clusterClient.asSecondaryAuthUser);
});
it('should reinstall when partial state found', async () => {
const builtInDefinitions = [mockEntityDefinition];
- const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
+ const clusterClient = elasticsearchClientMock.createScopedClusterClient();
+ const esClient = clusterClient.asInternalUser;
// mock partially installed definition
esClient.ingest.getPipeline.mockResolvedValue({});
esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 });
@@ -314,14 +315,18 @@ describe('install_entity_definition', () => {
});
await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
definitions: builtInDefinitions,
logger: loggerMock.create(),
});
- assertHasDeletedTransforms(mockEntityDefinition, esClient);
- assertHasUpgradedDefinition(mockEntityDefinition, soClient, esClient);
+ assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser);
+ assertHasUpgradedDefinition(
+ mockEntityDefinition,
+ soClient,
+ clusterClient.asSecondaryAuthUser
+ );
});
it('should reinstall when outdated version', async () => {
@@ -329,7 +334,8 @@ describe('install_entity_definition', () => {
...mockEntityDefinition,
version: semver.inc(mockEntityDefinition.version, 'major') ?? '0.0.0',
};
- const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
+ const clusterClient = elasticsearchClientMock.createScopedClusterClient();
+ const esClient = clusterClient.asInternalUser;
esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 });
const soClient = savedObjectsClientMock.create();
@@ -359,14 +365,14 @@ describe('install_entity_definition', () => {
});
await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
definitions: [updatedDefinition],
logger: loggerMock.create(),
});
- assertHasDeletedTransforms(mockEntityDefinition, esClient);
- assertHasUpgradedDefinition(updatedDefinition, soClient, esClient);
+ assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser);
+ assertHasUpgradedDefinition(updatedDefinition, soClient, clusterClient.asSecondaryAuthUser);
});
it('should reinstall when stale upgrade', async () => {
@@ -374,7 +380,8 @@ describe('install_entity_definition', () => {
...mockEntityDefinition,
version: semver.inc(mockEntityDefinition.version, 'major') ?? '0.0.0',
};
- const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
+ const clusterClient = elasticsearchClientMock.createScopedClusterClient();
+ const esClient = clusterClient.asInternalUser;
esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 });
const soClient = savedObjectsClientMock.create();
@@ -406,18 +413,19 @@ describe('install_entity_definition', () => {
});
await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
definitions: [updatedDefinition],
logger: loggerMock.create(),
});
- assertHasDeletedTransforms(mockEntityDefinition, esClient);
- assertHasUpgradedDefinition(updatedDefinition, soClient, esClient);
+ assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser);
+ assertHasUpgradedDefinition(updatedDefinition, soClient, clusterClient.asSecondaryAuthUser);
});
it('should reinstall when failed installation', async () => {
- const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
+ const clusterClient = elasticsearchClientMock.createScopedClusterClient();
+ const esClient = clusterClient.asInternalUser;
esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 });
const soClient = savedObjectsClientMock.create();
@@ -448,14 +456,18 @@ describe('install_entity_definition', () => {
});
await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
definitions: [mockEntityDefinition],
logger: loggerMock.create(),
});
- assertHasDeletedTransforms(mockEntityDefinition, esClient);
- assertHasUpgradedDefinition(mockEntityDefinition, soClient, esClient);
+ assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser);
+ assertHasUpgradedDefinition(
+ mockEntityDefinition,
+ soClient,
+ clusterClient.asSecondaryAuthUser
+ );
});
});
});
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts
index b4adedaf10374..bfc37ac52e2c1 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts
@@ -6,7 +6,7 @@
*/
import semver from 'semver';
-import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import { ElasticsearchClient, IScopedClusterClient } from '@kbn/core-elasticsearch-server';
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { EntityDefinition, EntityDefinitionUpdate } from '@kbn/entities-schema';
import { Logger } from '@kbn/logging';
@@ -29,6 +29,7 @@ import { mergeEntityDefinitionUpdate } from './helpers/merge_definition_update';
import { EntityDefinitionWithState } from './types';
import { stopLatestTransform, stopTransforms } from './stop_transforms';
import { deleteLatestTransform, deleteTransforms } from './delete_transforms';
+import { deleteIndices } from './delete_index';
export interface InstallDefinitionParams {
esClient: ElasticsearchClient;
@@ -49,10 +50,7 @@ export async function installEntityDefinition({
validateDefinitionCanCreateValidTransformIds(definition);
if (await entityDefinitionExists(soClient, definition.id)) {
- throw new EntityIdConflict(
- `Entity definition with [${definition.id}] already exists.`,
- definition
- );
+ throw new EntityIdConflict(`Entity definition [${definition.id}] already exists.`, definition);
}
try {
@@ -65,7 +63,7 @@ export async function installEntityDefinition({
return await install({ esClient, soClient, logger, definition: entityDefinition });
} catch (e) {
- logger.error(`Failed to install entity definition ${definition.id}: ${e}`);
+ logger.error(`Failed to install entity definition [${definition.id}]: ${e}`);
await stopLatestTransform(esClient, definition, logger);
await deleteLatestTransform(esClient, definition, logger);
@@ -90,28 +88,32 @@ export async function installEntityDefinition({
}
export async function installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
logger,
definitions,
-}: Omit & {
+}: Omit & {
+ clusterClient: IScopedClusterClient;
definitions: EntityDefinition[];
}): Promise {
if (definitions.length === 0) return [];
- logger.debug(`Starting installation of ${definitions.length} built-in definitions`);
+ logger.info(`Checking installation of ${definitions.length} built-in definitions`);
const installPromises = definitions.map(async (builtInDefinition) => {
const installedDefinition = await findEntityDefinitionById({
- esClient,
soClient,
+ esClient: clusterClient.asInternalUser,
id: builtInDefinition.id,
includeState: true,
});
if (!installedDefinition) {
+ // clean data from previous installation
+ await deleteIndices(clusterClient.asCurrentUser, builtInDefinition, logger);
+
return await installEntityDefinition({
definition: builtInDefinition,
- esClient,
+ esClient: clusterClient.asSecondaryAuthUser,
soClient,
logger,
});
@@ -127,15 +129,16 @@ export async function installBuiltInEntityDefinitions({
return installedDefinition;
}
- logger.debug(
+ logger.info(
`Detected failed or outdated installation of definition [${installedDefinition.id}] v${installedDefinition.version}, installing v${builtInDefinition.version}`
);
return await reinstallEntityDefinition({
soClient,
- esClient,
+ clusterClient,
logger,
definition: installedDefinition,
definitionUpdate: builtInDefinition,
+ deleteData: true,
});
});
@@ -150,22 +153,16 @@ async function install({
definition,
logger,
}: InstallDefinitionParams): Promise {
- logger.debug(
- () =>
- `Installing definition ${definition.id} v${definition.version}\n${JSON.stringify(
- definition,
- null,
- 2
- )}`
- );
+ logger.info(`Installing definition [${definition.id}] v${definition.version}`);
+ logger.debug(() => JSON.stringify(definition, null, 2));
- logger.debug(`Installing index templates for definition ${definition.id}`);
+ logger.debug(`Installing index templates for definition [${definition.id}]`);
const templates = await createAndInstallTemplates(esClient, definition, logger);
- logger.debug(`Installing ingest pipelines for definition ${definition.id}`);
+ logger.debug(`Installing ingest pipelines for definition [${definition.id}]`);
const pipelines = await createAndInstallIngestPipelines(esClient, definition, logger);
- logger.debug(`Installing transforms for definition ${definition.id}`);
+ logger.debug(`Installing transforms for definition [${definition.id}]`);
const transforms = await createAndInstallTransforms(esClient, definition, logger);
const updatedProps = await updateEntityDefinition(soClient, definition.id, {
@@ -177,20 +174,23 @@ async function install({
// stop and delete the current transforms and reinstall all the components
export async function reinstallEntityDefinition({
- esClient,
+ clusterClient,
soClient,
definition,
definitionUpdate,
logger,
-}: InstallDefinitionParams & {
+ deleteData = false,
+}: Omit & {
+ clusterClient: IScopedClusterClient;
definitionUpdate: EntityDefinitionUpdate;
+ deleteData?: boolean;
}): Promise {
try {
const updatedDefinition = mergeEntityDefinitionUpdate(definition, definitionUpdate);
logger.debug(
() =>
- `Reinstalling definition ${definition.id} from v${definition.version} to v${
+ `Reinstalling definition [${definition.id}] from v${definition.version} to v${
definitionUpdate.version
}\n${JSON.stringify(updatedDefinition, null, 2)}`
);
@@ -201,13 +201,17 @@ export async function reinstallEntityDefinition({
installStartedAt: new Date().toISOString(),
});
- logger.debug(`Deleting transforms for definition ${definition.id} v${definition.version}`);
- await stopAndDeleteTransforms(esClient, definition, logger);
+ logger.debug(`Deleting transforms for definition [${definition.id}] v${definition.version}`);
+ await stopAndDeleteTransforms(clusterClient.asSecondaryAuthUser, definition, logger);
+
+ if (deleteData) {
+ await deleteIndices(clusterClient.asCurrentUser, definition, logger);
+ }
return await install({
- esClient,
soClient,
logger,
+ esClient: clusterClient.asSecondaryAuthUser,
definition: updatedDefinition,
});
} catch (err) {
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap
index 94303584c45dc..86978b1b4df95 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap
+++ b/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap
@@ -3,7 +3,7 @@
exports[`generateLatestTransform(definition) should generate a valid latest transform 1`] = `
Object {
"_meta": Object {
- "definitionVersion": "1.0.0",
+ "definition_version": "1.0.0",
"managed": false,
},
"defer_validation": true,
@@ -42,7 +42,7 @@ Object {
},
},
},
- "entity.lastSeenTimestamp": Object {
+ "entity.last_seen_timestamp": Object {
"max": Object {
"field": "@timestamp",
},
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts
index c273469e3d3e3..c9d8cd9deef9b 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts
@@ -69,7 +69,7 @@ const generateTransformPutRequest = ({
return {
transform_id: transformId,
_meta: {
- definitionVersion: definition.version,
+ definition_version: definition.version,
managed: definition.managed,
},
defer_validation: true,
@@ -113,7 +113,7 @@ const generateTransformPutRequest = ({
aggs: {
...generateLatestMetricAggregations(definition),
...generateLatestMetadataAggregations(definition),
- 'entity.lastSeenTimestamp': {
+ 'entity.last_seen_timestamp': {
max: {
field: definition.latest.timestampField,
},
diff --git a/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts
index a4d44cd45ee17..66bc6da96619b 100644
--- a/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts
@@ -35,18 +35,20 @@ export async function upgradeBuiltInEntityDefinitions({
);
}
- const { esClient, soClient } = getClientsFromAPIKey({ apiKey, server });
+ const { clusterClient, soClient } = getClientsFromAPIKey({ apiKey, server });
logger.debug(`Starting built-in definitions upgrade`);
const upgradedDefinitions = await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
definitions,
logger,
});
await Promise.all(
- upgradedDefinitions.map((definition) => startTransforms(esClient, definition, logger))
+ upgradedDefinitions.map((definition) =>
+ startTransforms(clusterClient.asSecondaryAuthUser, definition, logger)
+ )
);
return { success: true, definitions: upgradedDefinitions };
diff --git a/x-pack/plugins/entity_manager/server/lib/entity_client.ts b/x-pack/plugins/entity_manager/server/lib/entity_client.ts
index 7e930d29bba73..babcbf35197e8 100644
--- a/x-pack/plugins/entity_manager/server/lib/entity_client.ts
+++ b/x-pack/plugins/entity_manager/server/lib/entity_client.ts
@@ -40,7 +40,11 @@ export class EntityClient {
definition: EntityDefinition;
installOnly?: boolean;
}) {
+ this.options.logger.info(
+ `Creating definition [${definition.id}] v${definition.version} (installOnly=${installOnly})`
+ );
const secondaryAuthClient = this.options.clusterClient.asSecondaryAuthUser;
+
const installedDefinition = await installEntityDefinition({
definition,
esClient: secondaryAuthClient,
@@ -62,16 +66,15 @@ export class EntityClient {
id: string;
definitionUpdate: EntityDefinitionUpdate;
}) {
- const secondaryAuthClient = this.options.clusterClient.asSecondaryAuthUser;
const definition = await findEntityDefinitionById({
id,
soClient: this.options.soClient,
- esClient: secondaryAuthClient,
+ esClient: this.options.clusterClient.asInternalUser,
includeState: true,
});
if (!definition) {
- const message = `Unable to find entity definition with [${id}]`;
+ const message = `Unable to find entity definition [${id}]`;
this.options.logger.error(message);
throw new EntityDefinitionNotFound(message);
}
@@ -86,25 +89,31 @@ export class EntityClient {
definition as EntityDefinitionWithState
).state.components.transforms.some((transform) => transform.running);
+ this.options.logger.info(
+ `Updating definition [${definition.id}] from v${definition.version} to v${definitionUpdate.version}`
+ );
const updatedDefinition = await reinstallEntityDefinition({
definition,
definitionUpdate,
soClient: this.options.soClient,
- esClient: secondaryAuthClient,
+ clusterClient: this.options.clusterClient,
logger: this.options.logger,
});
if (shouldRestartTransforms) {
- await startTransforms(secondaryAuthClient, updatedDefinition, this.options.logger);
+ await startTransforms(
+ this.options.clusterClient.asSecondaryAuthUser,
+ updatedDefinition,
+ this.options.logger
+ );
}
return updatedDefinition;
}
async deleteEntityDefinition({ id, deleteData = false }: { id: string; deleteData?: boolean }) {
- const secondaryAuthClient = this.options.clusterClient.asSecondaryAuthUser;
const definition = await findEntityDefinitionById({
id,
- esClient: secondaryAuthClient,
+ esClient: this.options.clusterClient.asInternalUser,
soClient: this.options.soClient,
});
@@ -112,9 +121,12 @@ export class EntityClient {
throw new EntityDefinitionNotFound(`Unable to find entity definition with [${id}]`);
}
+ this.options.logger.info(
+ `Uninstalling definition [${definition.id}] v${definition.version} (deleteData=${deleteData})`
+ );
await uninstallEntityDefinition({
definition,
- esClient: secondaryAuthClient,
+ esClient: this.options.clusterClient.asSecondaryAuthUser,
soClient: this.options.soClient,
logger: this.options.logger,
});
@@ -146,7 +158,7 @@ export class EntityClient {
builtIn?: boolean;
}) {
const definitions = await findEntityDefinitions({
- esClient: this.options.clusterClient.asSecondaryAuthUser,
+ esClient: this.options.clusterClient.asInternalUser,
soClient: this.options.soClient,
page,
perPage,
@@ -160,6 +172,7 @@ export class EntityClient {
}
async startEntityDefinition(definition: EntityDefinition) {
+ this.options.logger.info(`Starting transforms for definition [${definition.id}]`);
return startTransforms(
this.options.clusterClient.asSecondaryAuthUser,
definition,
@@ -168,6 +181,7 @@ export class EntityClient {
}
async stopEntityDefinition(definition: EntityDefinition) {
+ this.options.logger.info(`Stopping transforms for definition [${definition.id}]`);
return stopTransforms(
this.options.clusterClient.asSecondaryAuthUser,
definition,
diff --git a/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts b/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts
index ffa58cd9c0145..704c240e0c424 100644
--- a/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts
+++ b/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts
@@ -11,7 +11,6 @@ import {
IndicesPutIndexTemplateRequest,
} from '@elastic/elasticsearch/lib/api/types';
import { ElasticsearchClient, Logger } from '@kbn/core/server';
-import { entitiesHistoryBaseComponentTemplateConfig } from '../templates/components/base_history';
import { entitiesLatestBaseComponentTemplateConfig } from '../templates/components/base_latest';
import { entitiesEntityComponentTemplateConfig } from '../templates/components/entity';
import { entitiesEventComponentTemplateConfig } from '../templates/components/event';
@@ -38,11 +37,6 @@ export const installEntityManagerTemplates = async ({
logger: Logger;
}) => {
await Promise.all([
- upsertComponent({
- esClient,
- logger,
- component: entitiesHistoryBaseComponentTemplateConfig,
- }),
upsertComponent({
esClient,
logger,
diff --git a/x-pack/plugins/entity_manager/server/lib/utils.ts b/x-pack/plugins/entity_manager/server/lib/utils.ts
index aec8ffa940437..dfe14dcf20abd 100644
--- a/x-pack/plugins/entity_manager/server/lib/utils.ts
+++ b/x-pack/plugins/entity_manager/server/lib/utils.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import { IScopedClusterClient } from '@kbn/core-elasticsearch-server';
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { getFakeKibanaRequest } from '@kbn/security-plugin/server/authentication/api_keys/fake_kibana_request';
import { EntityManagerServerSetup } from '../types';
@@ -17,9 +17,9 @@ export const getClientsFromAPIKey = ({
}: {
apiKey: EntityDiscoveryAPIKey;
server: EntityManagerServerSetup;
-}): { esClient: ElasticsearchClient; soClient: SavedObjectsClientContract } => {
+}): { clusterClient: IScopedClusterClient; soClient: SavedObjectsClientContract } => {
const fakeRequest = getFakeKibanaRequest({ id: apiKey.id, api_key: apiKey.apiKey });
- const esClient = server.core.elasticsearch.client.asScoped(fakeRequest).asSecondaryAuthUser;
+ const clusterClient = server.core.elasticsearch.client.asScoped(fakeRequest);
const soClient = server.core.savedObjects.getScopedClient(fakeRequest);
- return { esClient, soClient };
+ return { clusterClient, soClient };
};
diff --git a/x-pack/plugins/entity_manager/server/routes/enablement/check.ts b/x-pack/plugins/entity_manager/server/routes/enablement/check.ts
index d0e2a572cb6f5..1c67643c5c902 100644
--- a/x-pack/plugins/entity_manager/server/routes/enablement/check.ts
+++ b/x-pack/plugins/entity_manager/server/routes/enablement/check.ts
@@ -61,13 +61,13 @@ export const checkEntityDiscoveryEnabledRoute = createEntityManagerServerRoute({
return response.ok({ body: { enabled: false, reason: ERROR_API_KEY_NOT_VALID } });
}
- const { esClient, soClient } = getClientsFromAPIKey({ apiKey, server });
+ const { clusterClient, soClient } = getClientsFromAPIKey({ apiKey, server });
const entityDiscoveryState = await Promise.all(
builtInDefinitions.map(async (builtInDefinition) => {
const definitions = await findEntityDefinitions({
- esClient,
soClient,
+ esClient: clusterClient.asSecondaryAuthUser,
id: builtInDefinition.id,
includeState: true,
});
diff --git a/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts b/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts
index f8629fe46497b..01208fe19d7a0 100644
--- a/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts
+++ b/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts
@@ -67,12 +67,13 @@ export const disableEntityDiscoveryRoute = createEntityManagerServerRoute({
includedHiddenTypes: [EntityDiscoveryApiKeyType.name],
});
+ logger.info('Disabling managed entity discovery');
await uninstallBuiltInEntityDefinitions({
entityClient,
deleteData: params.query.deleteData,
});
- server.logger.debug('reading entity discovery API key from saved object');
+ logger.debug('reading entity discovery API key from saved object');
const apiKey = await readEntityDiscoveryAPIKey(server);
// api key could be deleted outside of the apis, it does not affect the
// disablement flow
@@ -82,6 +83,7 @@ export const disableEntityDiscoveryRoute = createEntityManagerServerRoute({
ids: [apiKey.id],
});
}
+ logger.info('Managed entity discovery is disabled');
return response.ok({ body: { success: true } });
} catch (err) {
diff --git a/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts b/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts
index 1002c1e716df2..9a851e08b5673 100644
--- a/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts
+++ b/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts
@@ -93,6 +93,7 @@ export const enableEntityDiscoveryRoute = createEntityManagerServerRoute({
});
}
+ logger.info(`Enabling managed entity discovery (installOnly=${params.query.installOnly})`);
const soClient = core.savedObjects.getClient({
includedHiddenTypes: [EntityDiscoveryApiKeyType.name],
});
@@ -119,9 +120,9 @@ export const enableEntityDiscoveryRoute = createEntityManagerServerRoute({
await saveEntityDiscoveryAPIKey(soClient, apiKey);
- const esClient = core.elasticsearch.client.asSecondaryAuthUser;
+ const clusterClient = core.elasticsearch.client;
const installedDefinitions = await installBuiltInEntityDefinitions({
- esClient,
+ clusterClient,
soClient,
logger,
definitions: builtInDefinitions,
@@ -130,10 +131,11 @@ export const enableEntityDiscoveryRoute = createEntityManagerServerRoute({
if (!params.query.installOnly) {
await Promise.all(
installedDefinitions.map((installedDefinition) =>
- startTransforms(esClient, installedDefinition, logger)
+ startTransforms(clusterClient.asSecondaryAuthUser, installedDefinition, logger)
)
);
}
+ logger.info('Managed entity discovery is enabled');
return response.ok({ body: { success: true } });
} catch (err) {
diff --git a/x-pack/plugins/entity_manager/server/routes/entities/update.ts b/x-pack/plugins/entity_manager/server/routes/entities/update.ts
index 9cf72a9298d42..3b7ea8a03830d 100644
--- a/x-pack/plugins/entity_manager/server/routes/entities/update.ts
+++ b/x-pack/plugins/entity_manager/server/routes/entities/update.ts
@@ -5,21 +5,13 @@
* 2.0.
*/
-import {
- createEntityDefinitionQuerySchema,
- entityDefinitionUpdateSchema,
-} from '@kbn/entities-schema';
+import { entityDefinitionUpdateSchema } from '@kbn/entities-schema';
import { z } from '@kbn/zod';
import { EntitySecurityException } from '../../lib/entities/errors/entity_security_exception';
import { InvalidTransformError } from '../../lib/entities/errors/invalid_transform_error';
-import { findEntityDefinitionById } from '../../lib/entities/find_entity_definition';
-import { startTransforms } from '../../lib/entities/start_transforms';
-import {
- installationInProgress,
- reinstallEntityDefinition,
-} from '../../lib/entities/install_entity_definition';
-
import { createEntityManagerServerRoute } from '../create_entity_manager_server_route';
+import { EntityDefinitionNotFound } from '../../lib/entities/errors/entity_not_found';
+import { EntityDefinitionUpdateConflict } from '../../lib/entities/errors/entity_definition_update_conflict';
/**
* @openapi
@@ -29,13 +21,12 @@ import { createEntityManagerServerRoute } from '../create_entity_manager_server_
* tags:
* - definitions
* parameters:
- * - in: query
- * name: installOnly
- * description: If true, the definition transforms will not be started
- * required: false
+ * - in: path
+ * name: id
+ * description: The entity definition ID
* schema:
- * type: boolean
- * default: false
+ * type: string
+ * required: true
* requestBody:
* description: The definition properties to update
* required: true
@@ -63,58 +54,37 @@ export const updateEntityDefinitionRoute = createEntityManagerServerRoute({
endpoint: 'PATCH /internal/entities/definition/{id}',
params: z.object({
path: z.object({ id: z.string() }),
- query: createEntityDefinitionQuerySchema,
body: entityDefinitionUpdateSchema,
}),
- handler: async ({ context, response, params, logger }) => {
- const core = await context.core;
- const soClient = core.savedObjects.client;
- const esClient = core.elasticsearch.client.asCurrentUser;
+ handler: async ({ request, response, params, logger, getScopedClient }) => {
+ const entityClient = await getScopedClient({ request });
try {
- const installedDefinition = await findEntityDefinitionById({
- soClient,
- esClient,
+ const updatedDefinition = await entityClient.updateEntityDefinition({
id: params.path.id,
+ definitionUpdate: params.body,
});
- if (!installedDefinition) {
+ return response.ok({ body: updatedDefinition });
+ } catch (e) {
+ logger.error(e);
+
+ if (e instanceof EntityDefinitionNotFound) {
return response.notFound({
body: { message: `Entity definition [${params.path.id}] not found` },
});
}
- if (installedDefinition.managed) {
- return response.forbidden({
- body: { message: `Managed definition cannot be modified` },
- });
- }
-
- if (installationInProgress(installedDefinition)) {
+ if (e instanceof EntityDefinitionUpdateConflict) {
return response.conflict({
body: { message: `Entity definition [${params.path.id}] has changes in progress` },
});
}
- const updatedDefinition = await reinstallEntityDefinition({
- soClient,
- esClient,
- logger,
- definition: installedDefinition,
- definitionUpdate: params.body,
- });
-
- if (!params.query.installOnly) {
- await startTransforms(esClient, updatedDefinition, logger);
- }
-
- return response.ok({ body: updatedDefinition });
- } catch (e) {
- logger.error(e);
-
if (e instanceof EntitySecurityException || e instanceof InvalidTransformError) {
return response.customError({ body: e, statusCode: 400 });
}
+
return response.customError({ body: e, statusCode: 500 });
}
},
diff --git a/x-pack/plugins/entity_manager/server/templates/components/base_history.ts b/x-pack/plugins/entity_manager/server/templates/components/base_history.ts
deleted file mode 100644
index d0bdaa76152ec..0000000000000
--- a/x-pack/plugins/entity_manager/server/templates/components/base_history.ts
+++ /dev/null
@@ -1,36 +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 { ClusterPutComponentTemplateRequest } from '@elastic/elasticsearch/lib/api/types';
-import { ENTITY_HISTORY_BASE_COMPONENT_TEMPLATE_V1 } from '../../../common/constants_entities';
-
-export const entitiesHistoryBaseComponentTemplateConfig: ClusterPutComponentTemplateRequest = {
- name: ENTITY_HISTORY_BASE_COMPONENT_TEMPLATE_V1,
- _meta: {
- description:
- "Component template for the ECS fields used in the Elastic Entity Model's entity discovery framework's history data set",
- documentation: 'https://www.elastic.co/guide/en/ecs/current/ecs-base.html',
- ecs_version: '8.0.0',
- managed: true,
- },
- template: {
- mappings: {
- properties: {
- '@timestamp': {
- type: 'date',
- },
- labels: {
- type: 'object',
- },
- tags: {
- ignore_above: 1024,
- type: 'keyword',
- },
- },
- },
- },
-};
diff --git a/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts b/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts
index 6ee48b37bff1d..ef97a6fda3a3b 100644
--- a/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts
+++ b/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts
@@ -22,7 +22,7 @@ export const entitiesLatestBaseComponentTemplateConfig: ClusterPutComponentTempl
properties: {
entity: {
properties: {
- displayName: {
+ display_name: {
type: 'text',
fields: {
keyword: {
@@ -31,9 +31,6 @@ export const entitiesLatestBaseComponentTemplateConfig: ClusterPutComponentTempl
},
},
},
- firstSeenTimestamp: {
- type: 'date',
- },
},
},
labels: {
diff --git a/x-pack/plugins/entity_manager/server/templates/components/entity.ts b/x-pack/plugins/entity_manager/server/templates/components/entity.ts
index db93d0db77abf..fbd57ba66fc97 100644
--- a/x-pack/plugins/entity_manager/server/templates/components/entity.ts
+++ b/x-pack/plugins/entity_manager/server/templates/components/entity.ts
@@ -29,22 +29,22 @@ export const entitiesEntityComponentTemplateConfig: ClusterPutComponentTemplateR
ignore_above: 1024,
type: 'keyword',
},
- definitionId: {
+ definition_id: {
ignore_above: 1024,
type: 'keyword',
},
- definitionVersion: {
+ definition_version: {
ignore_above: 1024,
type: 'keyword',
},
- schemaVersion: {
+ schema_version: {
ignore_above: 1024,
type: 'keyword',
},
- lastSeenTimestamp: {
+ last_seen_timestamp: {
type: 'date',
},
- identityFields: {
+ identity_fields: {
type: 'keyword',
},
},
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts
index 5713c0a2b67fb..833e565ec00ef 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts
@@ -26,7 +26,6 @@ export interface EntityLatestServiceRaw {
interface Entity {
id: string;
- lastSeenTimestamp: string;
- firstSeenTimestamp: string;
- identityFields: string[];
+ last_seen_timestamp: string;
+ identity_fields: string[];
}
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts
index bb5c4f48b4125..e3dd0ef5e0d4e 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts
@@ -20,9 +20,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['metrics', 'logs'] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-1:test',
},
},
@@ -49,9 +48,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['foo'] },
entity: {
- firstSeenTimestamp: '2024-03-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-03-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-03-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-1:env-service-1',
},
},
@@ -63,9 +61,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['bar'] },
entity: {
- firstSeenTimestamp: '2024-03-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-03-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-03-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'apm-only-1:synthtrace-env-2',
},
},
@@ -77,9 +74,8 @@ describe('mergeEntities', () => {
agent: { name: ['java'] },
source_data_stream: { type: ['baz'] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-2:env-service-3',
},
},
@@ -91,9 +87,8 @@ describe('mergeEntities', () => {
agent: { name: ['java'] },
source_data_stream: { type: ['baz'] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-2:env-service-3',
},
},
@@ -127,9 +122,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['metrics', 'logs'] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-1:test',
},
},
@@ -141,9 +135,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['metrics', 'logs'] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-1:test',
},
},
@@ -155,9 +148,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['foo'] },
entity: {
- firstSeenTimestamp: '2024-23-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-23-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-23-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-1:prod',
},
},
@@ -183,9 +175,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: [] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name'],
id: 'service-1:test',
},
},
@@ -209,9 +200,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: [] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name'],
id: 'service-1:test',
},
},
@@ -222,9 +212,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: [] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name'],
id: 'service-1:test',
},
},
@@ -250,9 +239,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: [] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name'],
id: 'service-1:test',
},
},
@@ -276,9 +264,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: [] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name'],
id: 'service-1:test',
},
},
@@ -289,9 +276,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: [] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name'],
id: 'service-1:test',
},
},
@@ -318,9 +304,8 @@ describe('mergeEntities', () => {
agent: { name: ['nodejs'] },
source_data_stream: { type: ['metrics'] },
entity: {
- firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
- lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
- identityFields: ['service.name', 'service.environment'],
+ last_seen_timestamp: '2024-06-05T10:34:40.810Z',
+ identity_fields: ['service.name', 'service.environment'],
id: 'service-1:test',
},
},
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts
index e2ccc270b2a86..2f33c4728bd1a 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts
@@ -40,7 +40,7 @@ function mergeFunc(entity: EntityLatestServiceRaw, existingEntity?: MergedServic
const commonEntityFields = {
serviceName: entity.service.name,
agentName: entity.agent.name[0],
- lastSeenTimestamp: entity.entity.lastSeenTimestamp,
+ lastSeenTimestamp: entity.entity.last_seen_timestamp,
};
if (!existingEntity) {
diff --git a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts b/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts
index c4b48410456f8..b8d6219e6cd46 100644
--- a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts
+++ b/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts
@@ -26,7 +26,7 @@ describe('parseIdentityFieldValuesToKql', () => {
it('should return the value when identityFields is a single string', () => {
const entity: ServiceEntity = {
'agent.name': 'node',
- 'entity.identityFields': 'service.name',
+ 'entity.identity_fields': 'service.name',
'service.name': 'my-service',
'entity.type': 'service',
...commonEntityFields,
@@ -39,7 +39,7 @@ describe('parseIdentityFieldValuesToKql', () => {
it('should return values when identityFields is an array of strings', () => {
const entity: ServiceEntity = {
'agent.name': 'node',
- 'entity.identityFields': ['service.name', 'service.environment'],
+ 'entity.identity_fields': ['service.name', 'service.environment'],
'service.name': 'my-service',
'entity.type': 'service',
'service.environment': 'staging',
@@ -53,7 +53,7 @@ describe('parseIdentityFieldValuesToKql', () => {
it('should return an empty string if identityFields is empty string', () => {
const entity: ServiceEntity = {
'agent.name': 'node',
- 'entity.identityFields': '',
+ 'entity.identity_fields': '',
'service.name': 'my-service',
'entity.type': 'service',
...commonEntityFields,
@@ -65,7 +65,7 @@ describe('parseIdentityFieldValuesToKql', () => {
it('should return an empty array if identityFields is empty array', () => {
const entity: ServiceEntity = {
'agent.name': 'node',
- 'entity.identityFields': [],
+ 'entity.identity_fields': [],
'service.name': 'my-service',
'entity.type': 'service',
...commonEntityFields,
@@ -77,7 +77,7 @@ describe('parseIdentityFieldValuesToKql', () => {
it('should ignore fields that are not present in the entity', () => {
const entity: HostEntity = {
- 'entity.identityFields': ['host.name', 'foo.bar'],
+ 'entity.identity_fields': ['host.name', 'foo.bar'],
'host.name': 'my-host',
'entity.type': 'host',
'cloud.provider': null,
diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx
index c60490c8a12b1..fc73e490d4d05 100644
--- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx
+++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx
@@ -28,13 +28,13 @@ describe('AlertsBadge', () => {
it('render alerts badge for a host entity', () => {
const entity: HostEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'host',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'host.name',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'host.name',
'host.name': 'foo',
- 'entity.definitionId': 'host',
+ 'entity.definition_id': 'host',
'cloud.provider': null,
alertsCount: 1,
};
@@ -46,14 +46,14 @@ describe('AlertsBadge', () => {
});
it('render alerts badge for a service entity', () => {
const entity: ServiceEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'agent.name': 'node',
'entity.id': '1',
'entity.type': 'service',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'service.name',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'service.name',
'service.name': 'bar',
- 'entity.definitionId': 'host',
+ 'entity.definition_id': 'host',
'cloud.provider': null,
alertsCount: 5,
};
@@ -65,15 +65,15 @@ describe('AlertsBadge', () => {
});
it('render alerts badge for a service entity with multiple identity fields', () => {
const entity: ServiceEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'agent.name': 'node',
'entity.id': '1',
'entity.type': 'service',
- 'entity.displayName': 'foo',
- 'entity.identityFields': ['service.name', 'service.environment'],
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': ['service.name', 'service.environment'],
'service.name': 'bar',
'service.environment': 'prod',
- 'entity.definitionId': 'host',
+ 'entity.definition_id': 'host',
'cloud.provider': null,
alertsCount: 2,
};
diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx
index 36aad3d8e3a97..865e185eaa945 100644
--- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx
+++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx
@@ -41,13 +41,13 @@ describe('EntityName', () => {
it('returns host link', () => {
const entity: HostEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'host',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'host.name',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'host.name',
'host.name': 'foo',
- 'entity.definitionId': 'host',
+ 'entity.definition_id': 'host',
'cloud.provider': null,
};
render();
@@ -59,13 +59,13 @@ describe('EntityName', () => {
it('returns container link', () => {
const entity: ContainerEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'container',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'container.id',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'container.id',
'container.id': 'foo',
- 'entity.definitionId': 'container',
+ 'entity.definition_id': 'container',
'cloud.provider': null,
};
render();
@@ -77,13 +77,13 @@ describe('EntityName', () => {
it('returns service link without environment', () => {
const entity: ServiceEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'service',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'service.name',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'service.name',
'service.name': 'foo',
- 'entity.definitionId': 'service',
+ 'entity.definition_id': 'service',
'agent.name': 'bar',
};
render();
@@ -95,13 +95,13 @@ describe('EntityName', () => {
it('returns service link with environment', () => {
const entity: ServiceEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'service',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'service.name',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'service.name',
'service.name': 'foo',
- 'entity.definitionId': 'service',
+ 'entity.definition_id': 'service',
'agent.name': 'bar',
'service.environment': 'baz',
};
@@ -114,13 +114,13 @@ describe('EntityName', () => {
it('returns service link with first environment when it is an array', () => {
const entity: ServiceEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'service',
- 'entity.displayName': 'foo',
- 'entity.identityFields': 'service.name',
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': 'service.name',
'service.name': 'foo',
- 'entity.definitionId': 'service',
+ 'entity.definition_id': 'service',
'agent.name': 'bar',
'service.environment': ['baz', 'bar', 'foo'],
};
@@ -133,13 +133,13 @@ describe('EntityName', () => {
it('returns service link identity fields is an array', () => {
const entity: ServiceEntity = {
- 'entity.lastSeenTimestamp': 'foo',
+ 'entity.last_seen_timestamp': 'foo',
'entity.id': '1',
'entity.type': 'service',
- 'entity.displayName': 'foo',
- 'entity.identityFields': ['service.name', 'service.environment'],
+ 'entity.display_name': 'foo',
+ 'entity.identity_fields': ['service.name', 'service.environment'],
'service.name': 'foo',
- 'entity.definitionId': 'service',
+ 'entity.definition_id': 'service',
'agent.name': 'bar',
'service.environment': 'baz',
};
diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts
index 90bf2967b894d..0e6c663a00890 100644
--- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts
+++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts
@@ -29,14 +29,14 @@ describe('getIdentityFields', () => {
it('should return a Map with unique entity types and their respective identity fields', () => {
const serviceEntity: ServiceEntity = {
'agent.name': 'node',
- 'entity.identityFields': ['service.name', 'service.environment'],
+ 'entity.identity_fields': ['service.name', 'service.environment'],
'service.name': 'my-service',
'entity.type': 'service',
...commonEntityFields,
};
const hostEntity: HostEntity = {
- 'entity.identityFields': ['host.name'],
+ 'entity.identity_fields': ['host.name'],
'host.name': 'my-host',
'entity.type': 'host',
'cloud.provider': null,
@@ -44,7 +44,7 @@ describe('getIdentityFields', () => {
};
const containerEntity: ContainerEntity = {
- 'entity.identityFields': 'container.id',
+ 'entity.identity_fields': 'container.id',
'host.name': 'my-host',
'entity.type': 'container',
'cloud.provider': null,
diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx
index 2dc76d49c282f..f63cbb9c01618 100644
--- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx
+++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx
@@ -114,7 +114,7 @@ const formatEntityMetrics = (entity: EntityWithSource): string => {
.join(', ');
const entitySources = entity.sources.map((source) => source.dataStream).join(', ');
return dedent(`
- Entity name: ${entity.displayName};
+ Entity name: ${entity.display_name};
Entity type: ${entity.type};
Entity metrics: ${entityMetrics};
Entity data streams: ${entitySources}
diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts
index 00151f2029d21..0aa5d674702e3 100644
--- a/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts
+++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts
@@ -22,7 +22,7 @@ import {
} from '../clients/create_entities_es_client';
// the official types do not explicitly define sourceIndex in the schema, but it is present in the data at the time of writing this
-type EntitiesLatest = z.infer & { sourceIndex: string[] };
+type EntitiesLatest = z.infer & { source_index: string[] };
export async function getEntitiesWithSource({
serviceEnvironment,
@@ -51,21 +51,21 @@ export async function getEntitiesWithSource({
for (const response of entityResponses) {
const processedEntities = await Promise.all(
response.map(async (entity: EntitiesLatest) => {
- const sourceIndex = entity?.sourceIndex;
+ const sourceIndex = entity?.source_index;
if (!sourceIndex || !sourceIndex.length) return null;
const indices = await esClient.indices.get({ index: sourceIndex });
const sources = await fetchSources(indices);
return {
- identityFields: entity?.entity.identityFields,
+ identity_fields: entity?.entity.identity_fields,
id: entity?.entity.id,
- definitionId: entity?.entity.definitionId,
- lastSeenTimestamp: entity?.entity.lastSeenTimestamp,
- displayName: entity?.entity.displayName,
+ definition_id: entity?.entity.definition_id,
+ last_seen_timestamp: entity?.entity.last_seen_timestamp,
+ display_name: entity?.entity.display_name,
metrics: entity?.entity.metrics,
- schemaVersion: entity?.entity.schemaVersion,
- definitionVersion: entity?.entity.definitionVersion,
+ schema_version: entity?.entity.schema_version,
+ definition_version: entity?.entity.definition_version,
type: entity?.entity.type,
sources,
};
@@ -104,7 +104,7 @@ const getFetchEntitiesPromises = ({
hostName?: string;
containerId?: string;
serviceEnvironment?: string;
-}): Array>> => {
+}): Array>> => {
const shouldFilterForServiceEnvironment =
serviceEnvironment &&
serviceName &&
@@ -139,7 +139,7 @@ const getFetchEntitiesPromises = ({
return [containersPromise, hostsPromise, servicesPromise].filter(
(promise) => promise !== null
- ) as Array>>;
+ ) as Array>>;
};
const getFetchEntityPromise = ({
@@ -152,10 +152,10 @@ const getFetchEntityPromise = ({
shouldFetch: boolean;
shouldMatch: QueryDslQueryContainer[];
entitiesEsClient: EntitiesESClient;
-}): Promise> | null => {
+}): Promise> | null => {
return shouldFetch
? entitiesEsClient
- .search<{ sourceIndex: string[]; entity: EntitiesLatest['entity'] }>(index, {
+ .search<{ source_index: string[]; entity: EntitiesLatest['entity'] }>(index, {
body: {
query: {
bool: {
@@ -167,7 +167,7 @@ const getFetchEntityPromise = ({
})
.then((response) => {
return response.hits.hits.map((hit) => {
- return { sourceIndex: hit?._source.sourceIndex, entity: hit._source.entity };
+ return { source_index: hit?._source.source_index, entity: hit._source.entity };
});
})
: null;
diff --git a/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts b/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts
index 5652671a87281..e703cd487259c 100644
--- a/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts
+++ b/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts
@@ -149,9 +149,9 @@ export const PROFILE_INUSE_SPACE = 'profile.inuse_space.bytes';
export const ENTITY = 'entity';
export const ENTITY_ID = 'entity.id';
export const ENTITY_TYPE = 'entity.type';
-export const ENTITY_LAST_SEEN = 'entity.lastSeenTimestamp';
-export const ENTITY_FIRST_SEEN = 'entity.firstSeenTimestamp';
-export const ENTITY_DISPLAY_NAME = 'entity.displayName';
-export const ENTITY_DEFINITION_ID = 'entity.definitionId';
-export const ENTITY_IDENTITY_FIELDS = 'entity.identityFields';
+export const ENTITY_LAST_SEEN = 'entity.last_seen_timestamp';
+export const ENTITY_FIRST_SEEN = 'entity.first_seen_timestamp';
+export const ENTITY_DISPLAY_NAME = 'entity.display_name';
+export const ENTITY_DEFINITION_ID = 'entity.definition_id';
+export const ENTITY_IDENTITY_FIELDS = 'entity.identity_fields';
export const SOURCE_DATA_STREAM_TYPE = 'source_data_stream.type';
diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts
index c198a11556539..f4d2b848b726f 100644
--- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts
+++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts
@@ -67,7 +67,7 @@ const buildIngestPipeline = ({
{
set: {
field: '@timestamp',
- value: '{{entity.lastSeenTimestamp}}',
+ value: '{{entity.last_seen_timestamp}}',
},
},
{
diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts
index ad6a459f7ae80..96677a9c8a9b2 100644
--- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts
+++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts
@@ -15,13 +15,12 @@ export const removeEntityDefinitionFieldsStep = (): IngestProcessorContainer =>
remove: {
ignore_failure: true,
field: [
- 'entity.lastSeenTimestamp',
- 'entity.schemaVersion',
- 'entity.definitionVersion',
- 'entity.identityFields',
- 'entity.definitionId',
- 'entity.displayName',
- 'entity.firstSeenTimestamp',
+ 'entity.last_seen_timestamp',
+ 'entity.schema_version',
+ 'entity.definition_version',
+ 'entity.identity_fields',
+ 'entity.definition_id',
+ 'entity.display_name',
],
},
});
diff --git a/x-pack/test/api_integration/apis/entity_manager/definitions.ts b/x-pack/test/api_integration/apis/entity_manager/definitions.ts
index 468e53767b4e8..1a68169f6f386 100644
--- a/x-pack/test/api_integration/apis/entity_manager/definitions.ts
+++ b/x-pack/test/api_integration/apis/entity_manager/definitions.ts
@@ -101,26 +101,6 @@ export default function ({ getService }: FtrProviderContext) {
await uninstallDefinition(supertest, { id: mockDefinition.id });
});
-
- it('rejects updates to managed definitions', async () => {
- await installDefinition(supertest, {
- definition: { ...mockDefinition, managed: true },
- installOnly: true,
- });
-
- await updateDefinition(supertest, {
- id: mockDefinition.id,
- update: {
- version: '1.0.0',
- latest: {
- timestampField: '@updatedTimestampField',
- },
- },
- expectedCode: 403,
- });
-
- await uninstallDefinition(supertest, { id: mockDefinition.id });
- });
});
describe('entity data', () => {
diff --git a/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json b/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json
index 364ced91dc0b6..acbfceb9b55dd 100644
--- a/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json
+++ b/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json
@@ -45,15 +45,15 @@
},
"entity": {
"properties": {
- "definitionId": {
+ "definition_id": {
"type": "keyword",
"ignore_above": 1024
},
- "definitionVersion": {
+ "definition_version": {
"type": "keyword",
"ignore_above": 1024
},
- "displayName": {
+ "display_name": {
"type": "text",
"fields": {
"keyword": {
@@ -62,17 +62,14 @@
}
}
},
- "firstSeenTimestamp": {
- "type": "date"
- },
"id": {
"type": "keyword",
"ignore_above": 1024
},
- "identityFields": {
+ "identity_fields": {
"type": "keyword"
},
- "lastSeenTimestamp": {
+ "last_seen_timestamp": {
"type": "date"
},
"name": {
@@ -210,15 +207,15 @@
},
"entity": {
"properties": {
- "definitionId": {
+ "definition_id": {
"type": "keyword",
"ignore_above": 1024
},
- "definitionVersion": {
+ "definition_version": {
"type": "keyword",
"ignore_above": 1024
},
- "displayName": {
+ "display_name": {
"type": "text",
"fields": {
"keyword": {
@@ -227,17 +224,14 @@
}
}
},
- "firstSeenTimestamp": {
- "type": "date"
- },
"id": {
"type": "keyword",
"ignore_above": 1024
},
- "identityFields": {
+ "identity_fields": {
"type": "keyword"
},
- "lastSeenTimestamp": {
+ "last_seen_timestamp": {
"type": "date"
},
"name": {