Skip to content

Commit

Permalink
Filter OpenShift VMs by features
Browse files Browse the repository at this point in the history
Supported features:
1. NUMA
2. GPUs/Host Devices
3. Persistent TPM/EFI
4. Dedicated CPU

Signed-off-by: Radoslaw Szwajkowski <[email protected]>
  • Loading branch information
rszwajko committed Nov 30, 2023
1 parent 0bea166 commit 09f2fdd
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 9 deletions.
2 changes: 2 additions & 0 deletions packages/eslint-plugin/cspell.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ autoattach
virt
multiqueue
filesystems
bootloader
typeahead
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"Data centers": "Data centers",
"Data stores": "Data stores",
"Dates are compared in UTC. End of the interval is included.": "Dates are compared in UTC. End of the interval is included.",
"Dedicated CPU": "Dedicated CPU",
"Default": "Default",
"Default Transfer Network": "Default Transfer Network",
"Defines the CPU limits allocated to the main container in the controller pod. The default value is 500 milliCPU.": "Defines the CPU limits allocated to the main container in the controller pod. The default value is 500 milliCPU.",
Expand Down Expand Up @@ -122,8 +123,10 @@
"Error: VDDK init image must be valid.": "Error: VDDK init image must be valid.",
"Failed": "Failed",
"False": "False",
"Features": "Features",
"Filter by cluster": "Filter by cluster",
"Filter by endpoint": "Filter by endpoint",
"Filter by features": "Filter by features",
"Filter by flavor": "Filter by flavor",
"Filter by host": "Filter by host",
"Filter by image": "Filter by image",
Expand All @@ -137,6 +140,7 @@
"Filter by tenant": "Filter by tenant",
"Flavor": "Flavor",
"From": "From",
"GPUs/Host Devices": "GPUs/Host Devices",
"Hide values": "Hide values",
"Hooks for virtualization": "Hooks for virtualization",
"Host": "Host",
Expand Down Expand Up @@ -225,6 +229,7 @@
"No StorageMaps found in namespace <1>{namespace}</1>.": "No StorageMaps found in namespace <1>{namespace}</1>.",
"No StorageMaps found.": "No StorageMaps found.",
"Not Ready": "Not Ready",
"NUMA": "NUMA",
"Number of cluster in provider": "Number of cluster in provider",
"Number of data centers in provider": "Number of data centers in provider",
"Number of data stores in provider": "Number of data stores in provider",
Expand Down Expand Up @@ -264,6 +269,7 @@
"Owner": "Owner",
"Password": "Password",
"Path": "Path",
"Persistent TPM/EFI": "Persistent TPM/EFI",
"Plans": "Plans",
"Plans for virtualization": "Plans for virtualization",
"Please choose a NetworkAttachmentDefinition for default data transfer.": "Please choose a NetworkAttachmentDefinition for default data transfer.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import React from 'react';

import { EnumToTuple, ResourceFieldFactory } from '@kubev2v/common';

import { toVmFeatureEnum } from './utils/helpers/toVmFeatureEnum';
import { ProviderVirtualMachinesList, VmData } from './components';
import { OpenShiftVirtualMachinesRow } from './OpenShiftVirtualMachinesRow';
import { ProviderVirtualMachinesProps } from './ProviderVirtualMachines';
import { getVmPowerState } from './utils';
import { getOpenShiftFeatureMap, getVmPowerState } from './utils';

const openShiftVmFieldsMetadataFactory: ResourceFieldFactory = (t) => [
{
Expand Down Expand Up @@ -33,6 +34,19 @@ const openShiftVmFieldsMetadataFactory: ResourceFieldFactory = (t) => [
},
sortable: true,
},
{
resourceFieldId: 'features',
jsonPath: (data: VmData) => getOpenShiftFeatureMap(data?.vm),
label: t('Features'),
isVisible: true,
isIdentity: false,
filter: {
type: 'features',
placeholderLabel: t('Filter by features'),
values: EnumToTuple(toVmFeatureEnum(t)),
},
sortable: true,
},
{
resourceFieldId: 'template',
jsonPath: "$.vm.object.metadata.labels['vm.kubevirt.io/template']",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { Td, Tr } from '@patternfly/react-table';

import { PowerStateCellRenderer } from './components/PowerStateCellRenderer';
import { VmResourceLinkRenderer } from './components/VmResourceLinkRenderer';
import { VMCellProps, VmData } from './components';
import { VMCellProps, VmData, VmFeaturesCell } from './components';
import { getVmTemplate } from './utils';

const cellRenderers: Record<string, React.FC<VMCellProps>> = {
name: VmResourceLinkRenderer,
status: PowerStateCellRenderer,
template: ({ data }) => <TableCell>{getVmTemplate(data?.vm)}</TableCell>,
features: VmFeaturesCell,
};

const renderTd = ({ resourceData, resourceFieldId, resourceFields }: RenderTdProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ProviderData } from 'src/modules/Providers/utils';
import { useForkliftTranslation } from 'src/utils/i18n';

import {
EnumFilter,
loadUserSettings,
ResourceFieldFactory,
RowProps,
Expand Down Expand Up @@ -53,8 +54,9 @@ export const ProviderVirtualMachinesList: React.FC<ProviderVirtualMachinesListPr
userSettings={userSettings}
extraSupportedFilters={{
concerns: SearchableGroupedEnumFilter,
features: EnumFilter,
}}
extraSupportedMatchers={[concernsMatcher]}
extraSupportedMatchers={[concernsMatcher, featuresMatcher]}
/>
);
};
Expand All @@ -65,3 +67,8 @@ const concernsMatcher: ValueMatcher = {
Array.isArray(concerns) &&
concerns.some(({ category, label }) => category === filter || label === filter),
};

const featuresMatcher: ValueMatcher = {
filterType: 'features',
matchValue: (features: { [key: string]: boolean }) => (filter: string) => !!features?.[filter],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { TableCell } from 'src/modules/Providers/utils';
import { useForkliftTranslation } from 'src/utils/i18n';

import { Label } from '@patternfly/react-core';

import { getOpenShiftFeatureMap } from '../utils';
import { toVmFeatureEnum } from '../utils/helpers/toVmFeatureEnum';

import { VMCellProps } from './VMCellProps';

export const VmFeaturesCell: React.FC<VMCellProps> = ({ data }) => {
const { t } = useForkliftTranslation();
const featureToLabel = toVmFeatureEnum(t);
return (
<TableCell>
{Object.entries(getOpenShiftFeatureMap(data?.vm))
.filter(([, value]) => value)
.map(([key]) => (
<Label key={key} isCompact>
{featureToLabel[key]}
</Label>
))}
</TableCell>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export * from './PowerStateCellRenderer';
export * from './ProviderVirtualMachinesList';
export * from './VMCellProps';
export * from './VMConcernsCellRenderer';
export * from './VmFeaturesCell';
export * from './VMNameCellRenderer';
// @endindex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { VmFeatures } from 'src/utils/types';

import { ProviderVirtualMachine, V1DomainSpec } from '@kubev2v/types';

export const getOpenShiftFeatureMap = (vm: ProviderVirtualMachine): VmFeatures => {
if (vm.providerType !== 'openshift') {
return {};
}
const domain: V1DomainSpec = vm.object?.spec?.template?.spec?.domain;
if (!domain) {
return {};
}

return {
numa: !!domain.cpu?.numa,
gpusHostDevices: !!domain.devices?.gpus?.length || !!domain?.devices?.hostDevices?.length,
persistentTpmEfi:
!!domain?.devices?.tpm?.persistent || domain?.firmware?.bootloader?.efi?.persistent,
dedicatedCpu: !!domain?.cpu?.dedicatedCpuPlacement,
};
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// @index(['./*', /style/g], f => `export * from '${f.path}';`)
export * from './getOpenShiftFeatureMap';
export * from './getVmPowerState';
export * from './vmProps';
// @endindex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { VmFeatures } from 'src/utils/types';

export const toVmFeatureEnum = (t: (string) => string): { [k in keyof VmFeatures]: string } => ({
numa: t('NUMA'),
gpusHostDevices: t('GPUs/Host Devices'),
persistentTpmEfi: t('Persistent TPM/EFI'),
dedicatedCpu: t('Dedicated CPU'),
});
7 changes: 7 additions & 0 deletions packages/forklift-console-plugin/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,10 @@ export type ProviderStatus = (typeof ProviderStatusValues)[number];

export const MappingStatusValues = ['Ready', 'NotReady'] as const;
export type MappingStatus = (typeof MappingStatusValues)[number];

export interface VmFeatures {
numa?: boolean;
gpusHostDevices?: boolean;
persistentTpmEfi?: boolean;
dedicatedCpu?: boolean;
}
Loading

0 comments on commit 09f2fdd

Please sign in to comment.