From 9fc1f8a1f8001895cc0ef2c71b6776531df083ee Mon Sep 17 00:00:00 2001 From: Matan Schatzman Date: Tue, 4 Jun 2024 09:19:05 +0300 Subject: [PATCH] CNV-41586: Missing functions for sysprep customizr IT flow Signed-off-by: Matan Schatzman --- src/utils/store/customizeInstanceType.ts | 7 +- .../customizeInstanceType/utils/utils.ts | 6 + .../CustomizeInstanceTypeInitialRunTab.tsx | 8 +- .../components/InitialRunTabSysprep.tsx | 9 +- .../configuration/initialrun/utils/utils.ts | 107 ++++++++++++------ 5 files changed, 93 insertions(+), 44 deletions(-) diff --git a/src/utils/store/customizeInstanceType.ts b/src/utils/store/customizeInstanceType.ts index 622dae68a..c13e228ef 100644 --- a/src/utils/store/customizeInstanceType.ts +++ b/src/utils/store/customizeInstanceType.ts @@ -6,6 +6,7 @@ import { effect, signal } from '@preact/signals-react'; import { getCustomizeInstanceTypeSessionStorage, + mergeData, saveCustomizeInstanceTypeSessionStorage, } from './customizeInstanceType/utils/utils'; @@ -26,7 +27,9 @@ type UpdateCustomizeInstanceTypeArgs = { path?: string; }[]; -type UpdateCustomizeInstanceType = (args: UpdateCustomizeInstanceTypeArgs) => V1VirtualMachine; +export type UpdateCustomizeInstanceType = ( + args: UpdateCustomizeInstanceTypeArgs, +) => V1VirtualMachine; export const clearCustomizeInstanceType = () => { vmSignal.value = null; @@ -55,7 +58,7 @@ export const updateCustomizeInstanceType: UpdateCustomizeInstanceType = ( return; } - obj[part] = merge ? { ...obj[part], ...data } : data; + obj[part] = merge ? mergeData(obj[part], data) : data; }); }); }); diff --git a/src/utils/store/customizeInstanceType/utils/utils.ts b/src/utils/store/customizeInstanceType/utils/utils.ts index 4ac5f34ea..08a183ba5 100644 --- a/src/utils/store/customizeInstanceType/utils/utils.ts +++ b/src/utils/store/customizeInstanceType/utils/utils.ts @@ -19,3 +19,9 @@ export const getCustomizeInstanceTypeSessionStorage = (): V1VirtualMachine => { } return null; }; + +export const mergeData = (seedData, appendData) => { + return Array.isArray(seedData) || Array.isArray(appendData) + ? [...(seedData || []), ...(appendData || [])] + : { ...(seedData || {}), ...(appendData || {}) }; +}; diff --git a/src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeInitialRunTab.tsx b/src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeInitialRunTab.tsx index 20ec5b9d3..bd376adef 100644 --- a/src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeInitialRunTab.tsx +++ b/src/views/catalog/CustomizeInstanceType/tabs/configuration/utils/tabs/CustomizeInstanceTypeInitialRunTab.tsx @@ -3,7 +3,11 @@ import React from 'react'; import Loading from '@kubevirt-utils/components/Loading/Loading'; import SearchItem from '@kubevirt-utils/components/SearchItem/SearchItem'; import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation'; -import { updateVMCustomizeIT, vmSignal } from '@kubevirt-utils/store/customizeInstanceType'; +import { + updateCustomizeInstanceType, + updateVMCustomizeIT, + vmSignal, +} from '@kubevirt-utils/store/customizeInstanceType'; import { DescriptionList, Divider, @@ -30,7 +34,7 @@ const CustomizeInstanceTypeInitialRunTab = () => { - + ); diff --git a/src/views/virtualmachines/details/tabs/configuration/initialrun/components/InitialRunTabSysprep.tsx b/src/views/virtualmachines/details/tabs/configuration/initialrun/components/InitialRunTabSysprep.tsx index 46c2555d5..e158d499b 100644 --- a/src/views/virtualmachines/details/tabs/configuration/initialrun/components/InitialRunTabSysprep.tsx +++ b/src/views/virtualmachines/details/tabs/configuration/initialrun/components/InitialRunTabSysprep.tsx @@ -16,6 +16,7 @@ import { SysprepModal } from '@kubevirt-utils/components/SysprepModal/SysprepMod import VirtualMachineDescriptionItem from '@kubevirt-utils/components/VirtualMachineDescriptionItem/VirtualMachineDescriptionItem'; import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation'; import { getVolumes } from '@kubevirt-utils/resources/vm'; +import { UpdateCustomizeInstanceType } from '@kubevirt-utils/store/customizeInstanceType'; import { isEmpty } from '@kubevirt-utils/utils/utils'; import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; @@ -23,9 +24,10 @@ import { createSysprepConfigMap, patchVMWithExistingSysprepConfigMap } from '../ type InitialRunTabSysprepProps = { canUpdateVM: boolean; + onSubmit?: UpdateCustomizeInstanceType; vm: V1VirtualMachine; }; -const InitialRunTabSysprep: FC = ({ canUpdateVM, vm }) => { +const InitialRunTabSysprep: FC = ({ canUpdateVM, onSubmit, vm }) => { const { createModal } = useModal(); const vmVolumes = getVolumes(vm); @@ -44,10 +46,11 @@ const InitialRunTabSysprep: FC = ({ canUpdateVM, vm } const { [AUTOUNATTEND]: autoUnattend, [UNATTEND]: unattend } = externalSysprepConfig?.data || {}; - const onSysprepSelected = (name: string) => patchVMWithExistingSysprepConfigMap(name, vm); + const onSysprepSelected = (name: string) => + patchVMWithExistingSysprepConfigMap(name, vm, onSubmit); const onSysprepCreation = async (unattended: string, autounattend: string): Promise => - createSysprepConfigMap(unattended, autounattend, externalSysprepConfig, vm); + createSysprepConfigMap(unattended, autounattend, externalSysprepConfig, vm, onSubmit); return ( => { const vmVolumes = getVolumes(vm); const vmDisks = getDisks(vm); - await k8sPatch({ - data: [ - { - op: 'replace', - path: `/spec/template/spec/domain/devices/disks`, - value: [ - ...vmDisks.filter((disk) => disk?.name !== SYSPREP), - ...(!isEmpty(name) ? [sysprepDisk()] : []), - ], - }, - { - op: 'replace', - path: `/spec/template/spec/volumes`, - value: [ - ...vmVolumes.filter((vol) => vol?.name !== SYSPREP), - ...(!isEmpty(name) ? [sysprepVolume(name)] : []), + onSubmit + ? onSubmit([ + { + data: [ + ...(vmDisks || []).filter((disk) => disk?.name !== SYSPREP), + ...(!isEmpty(name) ? [sysprepDisk()] : []), + ], + path: `spec.template.spec.domain.devices.disks`, + }, + { + data: [ + ...(vmVolumes || []).filter((vol) => vol?.name !== SYSPREP), + ...(!isEmpty(name) ? [sysprepVolume(name)] : []), + ], + path: `spec.template.spec.volumes`, + }, + ]) + : await k8sPatch({ + data: [ + { + op: 'replace', + path: `/spec/template/spec/domain/devices/disks`, + value: [ + ...vmDisks.filter((disk) => disk?.name !== SYSPREP), + ...(!isEmpty(name) ? [sysprepDisk()] : []), + ], + }, + { + op: 'replace', + path: `/spec/template/spec/volumes`, + value: [ + ...vmVolumes.filter((vol) => vol?.name !== SYSPREP), + ...(!isEmpty(name) ? [sysprepVolume(name)] : []), + ], + }, ], - }, - ], - model: VirtualMachineModel, - resource: vm, - }); + model: VirtualMachineModel, + resource: vm, + }); }; export const createSysprepConfigMap = async ( @@ -50,6 +69,7 @@ export const createSysprepConfigMap = async ( autounattend: string, externalSysprepConfig: IoK8sApiCoreV1ConfigMap, vm: V1VirtualMachine, + onSubmit?: UpdateCustomizeInstanceType, ): Promise => { const vmVolumes = getVolumes(vm); const vmDisks = getDisks(vm); @@ -78,20 +98,33 @@ export const createSysprepConfigMap = async ( } await k8sCreate({ data: configMap, model: ConfigMapModel }); - await k8sPatch({ - data: [ - { - op: 'replace', - path: `/spec/template/spec/domain/devices/disks`, - value: [...vmDisks, sysprepDisk()], - }, - { - op: 'replace', - path: `/spec/template/spec/volumes`, - value: [...vmVolumes, sysprepVolume(configMap.metadata.name)], - }, - ], - model: VirtualMachineModel, - resource: vm, - }); + onSubmit + ? onSubmit([ + { + data: [sysprepDisk()], + merge: true, + path: 'spec.template.spec.domain.devices.disks', + }, + { + data: [sysprepVolume(configMap.metadata.name)], + merge: true, + path: `spec.template.spec.volumes`, + }, + ]) + : await k8sPatch({ + data: [ + { + op: 'replace', + path: `/spec/template/spec/domain/devices/disks`, + value: [...vmDisks, sysprepDisk()], + }, + { + op: 'replace', + path: `/spec/template/spec/volumes`, + value: [...vmVolumes, sysprepVolume(configMap.metadata.name)], + }, + ], + model: VirtualMachineModel, + resource: vm, + }); };