Skip to content

Commit b7beec8

Browse files
authored
MTV-3713: Enhance plan VM table and plan level validations (kubev2v#2123)
Resolves: MTV-3713 | Clarify migration concerns Signed-off-by: Sharon Gratch <[email protected]>
1 parent 5261ddb commit b7beec8

File tree

62 files changed

+1125
-598
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1125
-598
lines changed

locales/en/plugin__forklift-console-plugin.json

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
" tasks": " tasks",
3-
" To troubleshoot, check the <3>Virtual machines tab</3>.": " To troubleshoot, check the <3>Virtual machines tab</3>.",
43
".DiskIndex: initial volume index of the disk": ".DiskIndex: initial volume index of the disk",
54
".FileName: name of the file in the source provider (vmWare only, require guest agent)": ".FileName: name of the file in the source provider (vmWare only, require guest agent)",
65
".NetworkIndex: sequential index of the network interface (0-based)": ".NetworkIndex: sequential index of the network interface (0-based)",
@@ -222,6 +221,8 @@
222221
"Concern label": "Concern label",
223222
"Concern type": "Concern type",
224223
"Concerns": "Concerns",
224+
"Concerns (severity)": "Concerns (severity)",
225+
"Concerns (type)": "Concerns (type)",
225226
"Condition": "Condition",
226227
"Conditions": "Conditions",
227228
"Conditions not found": "Conditions not found",
@@ -257,6 +258,7 @@
257258
"Credentials": "Credentials",
258259
"Critical": "Critical",
259260
"Critical concerns": "Critical concerns",
261+
"critical concerns impacting your migration plan": "critical concerns impacting your migration plan",
260262
"Critical issues detected in your selected VMs will cause the migration to fail. Resolve these issues or remove the VMs from the plan before starting the migration.": "Critical issues detected in your selected VMs will cause the migration to fail. Resolve these issues or remove the VMs from the plan before starting the migration.",
261263
"Custom name template": "Custom name template",
262264
"Cutover": "Cutover",
@@ -395,6 +397,8 @@
395397
"Filter": "Filter",
396398
"Filter by {{activeFilterLabel}}": "Filter by {{activeFilterLabel}}",
397399
"Filter by cluster": "Filter by cluster",
400+
"Filter by concerns (severity)": "Filter by concerns (severity)",
401+
"Filter by concerns (type)": "Filter by concerns (type)",
398402
"Filter by critical concerns": "Filter by critical concerns",
399403
"Filter by description": "Filter by description",
400404
"Filter by endpoint": "Filter by endpoint",
@@ -472,6 +476,7 @@
472476
"If you want to keep the VM's static IP address after it has been migrated, check the \"Preserve static IPs\" box. By default, this is set to preserve the IPs. If you want the VM to get a new IP address via DHCP in the target environment, keep this box unchecked.": "If you want to keep the VM's static IP address after it has been migrated, check the \"Preserve static IPs\" box. By default, this is set to preserve the IPs. If you want the VM to get a new IP address via DHCP in the target environment, keep this box unchecked.",
473477
"Ignore network": "Ignore network",
474478
"Image": "Image",
479+
"Impacted resources": "Impacted resources",
475480
"In": "In",
476481
"In live migration, the source virtual machine continues to run until the migration is complete.": "In live migration, the source virtual machine continues to run until the migration is complete.",
477482
"In warm migration, the VM disks are copied incrementally using changed block tracking (CBT) snapshots.\n The snapshots are created at one-hour intervals by default.\n You can change the snapshot interval by updating the forklift-controller deployment.": "In warm migration, the VM disks are copied incrementally using changed block tracking (CBT) snapshots.\n The snapshots are created at one-hour intervals by default.\n You can change the snapshot interval by updating the forklift-controller deployment.",
@@ -555,10 +560,12 @@
555560
"Migrating virtualization workloads is a multi-step process. <2>Learn more</2>.": "Migrating virtualization workloads is a multi-step process. <2>Learn more</2>.",
556561
"Migrating your virtual machines": "Migrating your virtual machines",
557562
"Migration": "Migration",
563+
"Migration can not start until these critical concerns are resolved.": "Migration can not start until these critical concerns are resolved.",
558564
"Migration for Virtualization": "Migration for Virtualization",
559565
"Migration history": "Migration history",
560566
"Migration network maps are used to map network interfaces between source and target virtualization providers. At least one source and one target provider must be available in order to create a migration network map. <2>Learn more</2>.": "Migration network maps are used to map network interfaces between source and target virtualization providers. At least one source and one target provider must be available in order to create a migration network map. <2>Learn more</2>.",
561567
"Migration network maps are used to map networks between source and target providers.": "Migration network maps are used to map networks between source and target providers.",
568+
"Migration plan concerns": "Migration plan concerns",
562569
"Migration plan state information and progress": "Migration plan state information and progress",
563570
"Migration plans": "Migration plans",
564571
"Migration plans are used to document the moving of virtualization workloads from source providers to target providers.": "Migration plans are used to document the moving of virtualization workloads from source providers to target providers.",
@@ -904,6 +911,7 @@
904911
"Sets the memory limits allocated to the main container in the controller pod. The default value is 800Mi.": "Sets the memory limits allocated to the main container in the controller pod. The default value is 800Mi.",
905912
"Settings": "Settings",
906913
"Settings are applied across all projects on the Migration Toolkit for Virtualization operator.": "Settings are applied across all projects on the Migration Toolkit for Virtualization operator.",
914+
"Severity": "Severity",
907915
"SHA-1 fingerprint": "SHA-1 fingerprint",
908916
"Shared disks": "Shared disks",
909917
"Short snapshot polling interval": "Short snapshot polling interval",
@@ -957,7 +965,6 @@
957965
"Support": "Support",
958966
"Switch those VMs to cold migration or enable CBT in VMware before running the plan; otherwise the migration will fail.": "Switch those VMs to cold migration or enable CBT in VMware before running the plan; otherwise the migration will fail.",
959967
"Target and source": "Target and source",
960-
"Target name": "Target name",
961968
"Target network": "Target network",
962969
"Target network is required for mapping {{index}}.": "Target network is required for mapping {{index}}.",
963970
"Target power state": "Target power state",
@@ -992,9 +999,7 @@
992999
"the plan is configured with different hooks for different virtual machines": "the plan is configured with different hooks for different virtual machines",
9931000
"the plan is configured with more then one hook per step": "the plan is configured with more then one hook per step",
9941001
"The plan is currently in progress": "The plan is currently in progress",
995-
"The plan is not ready": "The plan is not ready",
9961002
"The plan LUKS decryption keys were manually configured": "The plan LUKS decryption keys were manually configured",
997-
"The plan migration might not work as expected": "The plan migration might not work as expected",
9981003
"The plan rootDisk keys was manually configured": "The plan rootDisk keys was manually configured",
9991004
"The pod logs are only available after \"image conversion\". If available, you can view them by expanding the “Migration Resources” section, looking under the “Pod” subheading, and clicking “View logs”.": "The pod logs are only available after \"image conversion\". If available, you can view them by expanding the “Migration Resources” section, looking under the “Pod” subheading, and clicking “View logs”.",
10001005
"The process is designed to reduce the service interruption to a few minutes, or even just seconds, during the final \"cutover\" phase.": "The process is designed to reduce the service interruption to a few minutes, or even just seconds, during the final \"cutover\" phase.",
@@ -1034,7 +1039,6 @@
10341039
"Tips and tricks": "Tips and tricks",
10351040
"To do a warm migration, you must set up VDDK for the selected VMware provider. If VDDK is not set up before starting the migration plan, the migration will fail.": "To do a warm migration, you must set up VDDK for the selected VMware provider. If VDDK is not set up before starting the migration plan, the migration will fail.",
10361041
"To resume, the cutover must be scheduled. When the cutover starts the {{vmCount}} VM{{isPlural}} included in this plan will shut down.": "To resume, the cutover must be scheduled. When the cutover starts the {{vmCount}} VM{{isPlural}} included in this plan will shut down.",
1037-
"To troubleshoot, check and edit your plan <2>mappings</2>.": "To troubleshoot, check and edit your plan <2>mappings</2>.",
10381042
"To troubleshoot, check the Forklift controller pod logs.": "To troubleshoot, check the Forklift controller pod logs.",
10391043
"To troubleshoot, view the network map details page\n and check the Forklift controller pod logs.": "To troubleshoot, view the network map details page\n and check the Forklift controller pod logs.",
10401044
"To troubleshoot, view the provider status available in the provider details page\n and check the Forklift controller pod logs.": "To troubleshoot, view the provider status available in the provider details page\n and check the Forklift controller pod logs.",
@@ -1120,7 +1124,9 @@
11201124
"View {{showAll}}{{vmCount}} VM{{isPlural}} in progress": "View {{showAll}}{{vmCount}} VM{{isPlural}} in progress",
11211125
"View {{showAll}}canceled VM{{isPlural}}": "View {{showAll}}canceled VM{{isPlural}}",
11221126
"View {{showAll}}VM{{isPlural}} that cannot start migration": "View {{showAll}}VM{{isPlural}} that cannot start migration",
1127+
"View all critical concerns": "View all critical concerns",
11231128
"View all plans": "View all plans",
1129+
"View critical concerns currently impacting your migration plan. All critical concerns must be addressed before the plan can be started.": "View critical concerns currently impacting your migration plan. All critical concerns must be addressed before the plan can be started.",
11241130
"View logs": "View logs",
11251131
"View network map details": "View network map details",
11261132
"View provider details": "View provider details",

src/components/Concerns/VirtualMachineConcernsCell.tsx

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,53 @@ import { TableEmptyCell } from 'src/modules/Providers/utils/components/TableCell
44
import type { VmData } from 'src/modules/Providers/views/details/tabs/VirtualMachines/components/VMCellProps';
55
import { PROVIDER_TYPES } from 'src/providers/utils/constants';
66

7-
import type { Concern } from '@kubev2v/types';
7+
import type { Concern, V1beta1PlanStatusConditions } from '@kubev2v/types';
88
import { Split, SplitItem } from '@patternfly/react-core';
99
import { isEmpty } from '@utils/helpers';
1010

1111
import ConcernPopover from './components/ConcernsPopover';
12-
import { groupConcernsByCategory } from './utils/category';
12+
import {
13+
getCategoryLabel,
14+
groupConcernsByCategory,
15+
groupConditionsByCategory,
16+
} from './utils/category';
1317
import { orderedConcernCategories } from './utils/constants';
1418

15-
const VirtualMachineConcernsCell: FC<{ vmData: VmData }> = ({ vmData }) => {
19+
type VirtualMachineConcernsCellProps = {
20+
vmData: VmData;
21+
conditions?: V1beta1PlanStatusConditions[];
22+
};
23+
24+
const VirtualMachineConcernsCell: FC<VirtualMachineConcernsCellProps> = ({
25+
conditions,
26+
vmData,
27+
}) => {
1628
const concerns: Concern[] =
1729
vmData?.vm?.providerType === PROVIDER_TYPES.openshift ? [] : vmData?.vm?.concerns;
18-
if (!concerns || isEmpty(concerns)) {
30+
if (isEmpty(concerns) && isEmpty(conditions)) {
1931
return <TableEmptyCell />;
2032
}
2133

2234
const groupedConcerns = groupConcernsByCategory(concerns);
35+
const groupedConditions = groupConditionsByCategory(conditions);
2336

2437
return (
2538
<TableCell>
2639
<Split hasGutter>
2740
{orderedConcernCategories.map((category) => {
2841
const hasConcernCategory = concerns?.find((concern) => concern.category === category);
42+
const hasConditionCategory = conditions?.find(
43+
(condition) => getCategoryLabel(condition.category) === category,
44+
);
2945

30-
if (hasConcernCategory) {
46+
if (hasConcernCategory || hasConditionCategory) {
3147
return (
3248
<SplitItem key={category}>
33-
<ConcernPopover category={category} concerns={groupedConcerns[category] || []} />
49+
<ConcernPopover
50+
category={category}
51+
concerns={groupedConcerns[category] || []}
52+
conditions={groupedConditions[category] || []}
53+
/>
3454
</SplitItem>
3555
);
3656
}

src/components/Concerns/components/ConcernsList.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
import type { FC } from 'react';
22

3-
import type { Concern } from '@kubev2v/types';
3+
import type { Concern, V1beta1PlanStatusConditions } from '@kubev2v/types';
44
import { Stack, StackItem } from '@patternfly/react-core';
55

66
import { getCategoryIcon } from '../utils/category';
77

8-
const ConcernList: FC<{ concerns: Concern[] }> = ({ concerns }) => (
8+
const ConcernList: FC<{ concerns: Concern[]; conditions: V1beta1PlanStatusConditions[] }> = ({
9+
concerns,
10+
conditions,
11+
}) => (
912
<Stack>
1013
{concerns.map((concern) => (
1114
<StackItem key={concern.category}>
1215
{getCategoryIcon(concern.category)} {concern.label}
1316
</StackItem>
1417
))}
18+
{conditions.map((condition) => (
19+
<StackItem key={condition.category}>
20+
{getCategoryIcon(condition.category)} {condition.message}
21+
</StackItem>
22+
))}
1523
</Stack>
1624
);
1725

src/components/Concerns/components/ConcernsPopover.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { FC } from 'react';
22

3-
import type { Concern } from '@kubev2v/types';
3+
import type { Concern, V1beta1PlanStatusConditions } from '@kubev2v/types';
44
import { Button, ButtonVariant, Label, Popover } from '@patternfly/react-core';
55
import { isEmpty } from '@utils/helpers';
66
import { useForkliftTranslation } from '@utils/i18n';
@@ -12,21 +12,24 @@ import ConcernList from './ConcernsList';
1212
const ConcernPopover: FC<{
1313
category: string;
1414
concerns: Concern[];
15-
}> = ({ category, concerns }) => {
15+
conditions: V1beta1PlanStatusConditions[];
16+
}> = ({ category, concerns, conditions }) => {
1617
const { t } = useForkliftTranslation();
1718

18-
if (isEmpty(concerns)) return null;
19+
if (isEmpty(concerns) && isEmpty(conditions)) return null;
20+
21+
const totalLength = concerns.length + conditions.length;
1922

2023
return (
2124
<Popover
2225
aria-label={`${category} popover`}
2326
headerContent={getCategoryTitle(category)}
24-
bodyContent={<ConcernList concerns={concerns} />}
25-
footerContent={t('Total: {{length}}', { length: concerns.length })}
27+
bodyContent={<ConcernList concerns={concerns} conditions={conditions} />}
28+
footerContent={t('Total: {{length}}', { length: totalLength })}
2629
data-testid="concerns-popover"
2730
>
2831
<Button isInline variant={ButtonVariant.link}>
29-
<Label status={getCategoryStatus(category)}>{concerns.length}</Label>
32+
<Label status={getCategoryStatus(category)}>{totalLength}</Label>
3033
</Button>
3134
</Popover>
3235
);

src/components/Concerns/components/ConcernsTable.tsx

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/components/Concerns/utils/category.tsx

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,42 @@
11
import type { ReactNode } from 'react';
22

3-
import type { Concern } from '@kubev2v/types';
3+
import type { Concern, V1beta1PlanStatusConditions } from '@kubev2v/types';
44
import type { LabelProps } from '@patternfly/react-core';
55
import {
66
ExclamationCircleIcon,
77
ExclamationTriangleIcon,
88
InfoCircleIcon,
99
} from '@patternfly/react-icons';
10+
import { isEmpty } from '@utils/helpers';
1011
import { t } from '@utils/i18n';
1112

1213
import { type ConcernCategory, ConcernCategoryOptions } from './constants';
1314

15+
const CATEGORY_LABELS: Record<ConcernCategory, string> = {
16+
[ConcernCategoryOptions.Critical]: 'Critical',
17+
[ConcernCategoryOptions.Information]: 'Information',
18+
[ConcernCategoryOptions.Warn]: 'Warning',
19+
[ConcernCategoryOptions.Warning]: 'Warning',
20+
};
21+
1422
const CATEGORY_TITLES: Record<ConcernCategory, string> = {
1523
[ConcernCategoryOptions.Critical]: t('Critical concerns'),
1624
[ConcernCategoryOptions.Information]: t('Information concerns'),
25+
[ConcernCategoryOptions.Warn]: t('Warning concerns'),
1726
[ConcernCategoryOptions.Warning]: t('Warning concerns'),
1827
};
1928

2029
const CATEGORY_ICONS: Record<ConcernCategory, ReactNode> = {
2130
[ConcernCategoryOptions.Critical]: <ExclamationCircleIcon color="#C9190B" />,
2231
[ConcernCategoryOptions.Information]: <InfoCircleIcon color="#2B9AF3" />,
32+
[ConcernCategoryOptions.Warn]: <ExclamationTriangleIcon color="#F0AB00" />,
2333
[ConcernCategoryOptions.Warning]: <ExclamationTriangleIcon color="#F0AB00" />,
2434
};
2535

2636
const CATEGORY_STATUS: Record<ConcernCategory, LabelProps['status'] | undefined> = {
2737
[ConcernCategoryOptions.Critical]: 'danger',
2838
[ConcernCategoryOptions.Information]: 'info',
39+
[ConcernCategoryOptions.Warn]: 'warning',
2940
[ConcernCategoryOptions.Warning]: 'warning',
3041
};
3142

@@ -44,15 +55,40 @@ export const getCategoryStatus = (category: string): LabelProps['status'] | unde
4455
return isConcernCategory(category) ? CATEGORY_STATUS[category] : undefined;
4556
};
4657

58+
export const getCategoryLabel = (category: string): string => {
59+
return CATEGORY_LABELS[category as ConcernCategory];
60+
};
61+
4762
export const groupConcernsByCategory = (
4863
concerns: Concern[] = [],
4964
): Record<ConcernCategory, Concern[]> => {
5065
return concerns.reduce<Record<string, Concern[]>>(
5166
(acc, concern) => {
52-
if (!acc[concern.category]) {
53-
acc[concern.category] = [];
67+
if (isEmpty(concern)) return acc;
68+
if (isEmpty(acc[concern?.category])) {
69+
acc[concern?.category] = [];
70+
}
71+
acc[concern?.category].push(concern);
72+
return acc;
73+
},
74+
{
75+
[ConcernCategoryOptions.Critical]: [],
76+
[ConcernCategoryOptions.Information]: [],
77+
[ConcernCategoryOptions.Warning]: [],
78+
},
79+
);
80+
};
81+
82+
export const groupConditionsByCategory = (
83+
conditions: V1beta1PlanStatusConditions[] = [],
84+
): Record<ConcernCategory, V1beta1PlanStatusConditions[]> => {
85+
return conditions.reduce<Record<string, V1beta1PlanStatusConditions[]>>(
86+
(acc, condition) => {
87+
if (isEmpty(getCategoryLabel(condition?.category))) return acc;
88+
if (isEmpty(acc[getCategoryLabel(condition?.category)])) {
89+
acc[condition?.category] = [];
5490
}
55-
acc[concern.category].push(concern);
91+
acc[getCategoryLabel(condition?.category)].push(condition);
5692
return acc;
5793
},
5894
{

0 commit comments

Comments
 (0)