From c13a194b23167889bdfd4d2fe7a0ce38550ebbf2 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 26 Oct 2020 11:37:35 +0100 Subject: [PATCH] [ILM] Update show/hide data tier logic on cloud (#81455) * Update show/hide data tier logic only show data tier options on cloud if the cluster is not using the deprecated node.data config and there is a data_* role present. this will likely be a role like data_content which will ensure that the cluster is configured with the new data tier roles. * refactor node role types for clarity * added comment Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> # Conflicts: # x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts --- .../__jest__/components/edit_policy.test.tsx | 3 ++- .../common/constants/data_tiers.ts | 8 ++++---- .../common/types/api.ts | 4 ++-- .../common/types/index.ts | 17 +++++++++++++---- .../get_available_node_roles_for_phase.ts | 4 ++-- .../data_tiers/is_node_role_first_preference.ts | 4 ++-- .../default_allocation_notice.tsx | 8 ++++---- .../shared/data_tier_allocation_field.tsx | 13 +++++++++---- .../routes/api/nodes/register_list_route.ts | 10 ++++------ 9 files changed, 42 insertions(+), 29 deletions(-) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx index fc867aa2774b4c..f7acb1066981b3 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx @@ -742,7 +742,8 @@ describe('edit policy', () => { test('should hide data tier option on cloud using legacy node role configuration', async () => { http.setupNodeListResponse({ nodesByAttributes: { test: ['123'] }, - nodesByRoles: { data: ['test'], data_hot: ['test'], data_warm: ['test'] }, + // On cloud, if using legacy config there will not be any "data_*" roles set. + nodesByRoles: { data: ['test'] }, isUsingDeprecatedDataRoleConfig: true, }); const rendered = mountWithIntl(component); diff --git a/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts b/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts index 8a1acf72949e68..f6b9506f9068cc 100644 --- a/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts +++ b/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts @@ -6,13 +6,13 @@ // Order of node roles matters here, the warm phase prefers allocating data // to the data_warm role. -import { NodeDataRole, PhaseWithAllocation } from '../types'; +import { DataTierRole, PhaseWithAllocation } from '../types'; -const WARM_PHASE_NODE_PREFERENCE: NodeDataRole[] = ['data_warm', 'data_hot']; +const WARM_PHASE_NODE_PREFERENCE: DataTierRole[] = ['data_warm', 'data_hot']; -const COLD_PHASE_NODE_PREFERENCE: NodeDataRole[] = ['data_cold', 'data_warm', 'data_hot']; +const COLD_PHASE_NODE_PREFERENCE: DataTierRole[] = ['data_cold', 'data_warm', 'data_hot']; -export const phaseToNodePreferenceMap: Record = Object.freeze({ +export const phaseToNodePreferenceMap: Record = Object.freeze({ warm: WARM_PHASE_NODE_PREFERENCE, cold: COLD_PHASE_NODE_PREFERENCE, }); diff --git a/x-pack/plugins/index_lifecycle_management/common/types/api.ts b/x-pack/plugins/index_lifecycle_management/common/types/api.ts index ccdd7fcb11778d..b7ca16ac46ddef 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/api.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/api.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { NodeDataRoleWithCatchAll } from '.'; +import { AnyDataRole } from '.'; export interface ListNodesRouteResponse { nodesByAttributes: { [attributePair: string]: string[] }; - nodesByRoles: { [role in NodeDataRoleWithCatchAll]?: string[] }; + nodesByRoles: { [role in AnyDataRole]?: string[] }; /** * A flag to indicate whether a node is using `settings.node.data` which is the now deprecated way cloud configured diff --git a/x-pack/plugins/index_lifecycle_management/common/types/index.ts b/x-pack/plugins/index_lifecycle_management/common/types/index.ts index 1f41370e48f180..737e5a551aae82 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/index.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/index.ts @@ -9,8 +9,17 @@ export * from './api'; export * from './policies'; /** - * These roles reflect how nodes are stratified into different data tiers. The "data" role - * is a catch-all that can be used to store data in any phase. + * These roles reflect how nodes are stratified into different data tiers. */ -export type NodeDataRole = 'data_hot' | 'data_warm' | 'data_cold'; -export type NodeDataRoleWithCatchAll = 'data' | NodeDataRole; +export type DataTierRole = 'data_hot' | 'data_warm' | 'data_cold'; + +/** + * The "data_content" role can store all data the ES stack uses for feature + * functionality like security-related indices. + */ +export type DataRole = 'data_content' | DataTierRole; + +/** + * The "data" role can store data allocated to any tier. + */ +export type AnyDataRole = 'data' | DataRole; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts index 6daae57330886d..179de0b1d8c8e4 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts @@ -5,14 +5,14 @@ */ import { - NodeDataRole, + DataTierRole, ListNodesRouteResponse, PhaseWithAllocation, } from '../../../../common/types'; import { phaseToNodePreferenceMap } from '../../../../common/constants'; -export type AllocationNodeRole = NodeDataRole | 'none'; +export type AllocationNodeRole = DataTierRole | 'none'; /** * Given a phase and current cluster node roles, determine which nodes the phase diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts index 872efa740b1316..fff640a5eb9575 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { NodeDataRole, PhaseWithAllocation } from '../../../../common/types'; +import { DataTierRole, PhaseWithAllocation } from '../../../../common/types'; import { phaseToNodePreferenceMap } from '../../../../common/constants'; -export const isNodeRoleFirstPreference = (phase: PhaseWithAllocation, nodeRole: NodeDataRole) => { +export const isNodeRoleFirstPreference = (phase: PhaseWithAllocation, nodeRole: DataTierRole) => { return phaseToNodePreferenceMap[phase][0] === nodeRole; }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx index 42f9e8494a0b3b..3d0052c69607b4 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx @@ -8,11 +8,11 @@ import { i18n } from '@kbn/i18n'; import React, { FunctionComponent } from 'react'; import { EuiCallOut } from '@elastic/eui'; -import { PhaseWithAllocation, NodeDataRole } from '../../../../../../common/types'; +import { PhaseWithAllocation, DataTierRole } from '../../../../../../common/types'; import { AllocationNodeRole } from '../../../../lib'; -const i18nTextsNodeRoleToDataTier: Record = { +const i18nTextsNodeRoleToDataTier: Record = { data_hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel', { defaultMessage: 'hot', }), @@ -31,7 +31,7 @@ const i18nTexts = { 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title', { defaultMessage: 'No nodes assigned to the warm tier' } ), - body: (nodeRole: NodeDataRole) => + body: (nodeRole: DataTierRole) => i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm', { defaultMessage: 'This policy will move data in the warm phase to {tier} tier nodes instead.', @@ -43,7 +43,7 @@ const i18nTexts = { 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold.title', { defaultMessage: 'No nodes assigned to the cold tier' } ), - body: (nodeRole: NodeDataRole) => + body: (nodeRole: DataTierRole) => i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold', { defaultMessage: 'This policy will move data in the cold phase to {tier} tier nodes instead.', diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx index 22cc2e0ce99b52..bee06acdbbadd9 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx @@ -55,6 +55,10 @@ export const DataTierAllocationField: FunctionComponent = ({ return ( {({ nodesByRoles, nodesByAttributes, isUsingDeprecatedDataRoleConfig }) => { + const hasDataNodeRoles = Object.keys(nodesByRoles).some((nodeRole) => + // match any of the "data_" roles, including data_content. + nodeRole.trim().startsWith('data_') + ); const hasNodeAttrs = Boolean(Object.keys(nodesByAttributes ?? {}).length); const renderNotice = () => { @@ -62,7 +66,8 @@ export const DataTierAllocationField: FunctionComponent = ({ case 'default': const isCloudEnabled = cloud?.isCloudEnabled ?? false; if (isCloudEnabled && phase === 'cold') { - const isUsingNodeRolesAllocation = !isUsingDeprecatedDataRoleConfig; + const isUsingNodeRolesAllocation = + !isUsingDeprecatedDataRoleConfig && hasDataNodeRoles; const hasNoNodesWithNodeRole = !nodesByRoles.data_cold?.length; if (isUsingNodeRolesAllocation && hasNoNodesWithNodeRole) { @@ -120,9 +125,9 @@ export const DataTierAllocationField: FunctionComponent = ({ phaseData={phaseData} isShowingErrors={isShowingErrors} nodes={nodesByAttributes} - disableDataTierOption={ - !!(isUsingDeprecatedDataRoleConfig && cloud?.isCloudEnabled) - } + disableDataTierOption={Boolean( + cloud?.isCloudEnabled && !hasDataNodeRoles && isUsingDeprecatedDataRoleConfig + )} /> {/* Data tier related warnings and call-to-action notices */} diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts index 4a176545743d00..d7fdda95327707 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts @@ -5,9 +5,7 @@ */ import { LegacyAPICaller } from 'src/core/server'; - -import { ListNodesRouteResponse, NodeDataRole } from '../../../../common/types'; - +import { ListNodesRouteResponse, DataTierRole } from '../../../../common/types'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../../../services'; @@ -41,10 +39,10 @@ export function convertSettingsIntoLists( } } - const dataRoles = nodeSettings.roles.filter((r) => r.startsWith('data')) as NodeDataRole[]; + const dataRoles = nodeSettings.roles.filter(r => r.startsWith('data')) as DataTierRole[]; for (const role of dataRoles) { - accum.nodesByRoles[role as NodeDataRole] = accum.nodesByRoles[role] ?? []; - accum.nodesByRoles[role as NodeDataRole]!.push(nodeId); + accum.nodesByRoles[role as DataTierRole] = accum.nodesByRoles[role] ?? []; + accum.nodesByRoles[role as DataTierRole]!.push(nodeId); } // If we detect a single node using legacy "data:true" setting we know we are not using data roles for