diff --git a/pkg/harvester/components/vm-migration/ReviewMigrationStep.vue b/pkg/harvester/components/vm-migration/ReviewMigrationStep.vue index 35cd2e67..2bdd4c3a 100644 --- a/pkg/harvester/components/vm-migration/ReviewMigrationStep.vue +++ b/pkg/harvester/components/vm-migration/ReviewMigrationStep.vue @@ -5,8 +5,10 @@ import Loading from '@shell/components/Loading'; import { Banner } from '@components/Banner'; import { RcItemCard } from '@components/RcItemCard'; import { LabeledInput } from '@components/Form/LabeledInput'; +import LabeledSelect from '@shell/components/form/LabeledSelect'; import MappingsCell from '../MappingsCell'; import { useI18n } from '@shell/composables/useI18n'; +import { NAMESPACE } from '@shell/config/types'; import { HCI } from '../../types'; import { FORKLIFT_NAMESPACE } from '../../config/harvester-map'; import { @@ -30,18 +32,27 @@ const vms = ref([]); const networkMappings = ref([]); const storageMappings = ref([]); const planName = ref(''); +const targetNamespace = ref(''); +const namespaceOptions = ref([]); const errors = ref([]); const loading = ref(true); // Restore persisted state planName.value = props.stepData.planName; +targetNamespace.value = props.stepData.targetNamespace || ''; -const NAMESPACE = FORKLIFT_NAMESPACE; -const TARGET_NAMESPACE = 'default'; +const NS = FORKLIFT_NAMESPACE; watch(planName, (val) => { props.stepData.planName = val; - emit('ready', !!val); +}, { immediate: true }); + +watch(targetNamespace, (val) => { + props.stepData.targetNamespace = val; +}); + +watch([planName, targetNamespace], ([name, namespace]) => { + emit('ready', !!name && !!namespace); }, { immediate: true }); const totalVCpu = computed(() => vms.value.reduce((sum, vm) => sum + (vm.cpuCount || vm.numCPU || 0), 0)); @@ -103,13 +114,13 @@ const startMigrationAction = async() => { apiVersion: FORKLIFT_API_VERSION, kind: 'Provider', name: props.providerName, - namespace: NAMESPACE, + namespace: NS, }, destination: { apiVersion: FORKLIFT_API_VERSION, kind: 'Provider', name: 'host', - namespace: NAMESPACE, + namespace: NS, }, }; @@ -118,15 +129,15 @@ const startMigrationAction = async() => { const networkMap = await store.dispatch(`${ inStore }/create`, { type: HCI.FORKLIFT_NETWORK_MAP, - metadata: { name: networkMapName, namespace: NAMESPACE }, - spec: { map: buildNetworkMapEntries(props.mappingEntries?.networkEntries || [], NAMESPACE), provider: providerRef }, + metadata: { name: networkMapName, namespace: NS }, + spec: { map: buildNetworkMapEntries(props.mappingEntries?.networkEntries || [], NS), provider: providerRef }, }); await networkMap.save(); const storageMap = await store.dispatch(`${ inStore }/create`, { type: HCI.FORKLIFT_STORAGE_MAP, - metadata: { name: storageMapName, namespace: NAMESPACE }, + metadata: { name: storageMapName, namespace: NS }, spec: { map: buildStorageMapEntries(props.mappingEntries?.storageEntries || []), provider: providerRef }, }); @@ -134,7 +145,7 @@ const startMigrationAction = async() => { const plan = await store.dispatch(`${ inStore }/create`, { type: HCI.FORKLIFT_PLAN, - metadata: { name: planName.value, namespace: NAMESPACE }, + metadata: { name: planName.value, namespace: NS }, spec: { provider: providerRef, map: { @@ -142,16 +153,16 @@ const startMigrationAction = async() => { apiVersion: FORKLIFT_API_VERSION, kind: 'NetworkMap', name: networkMapName, - namespace: NAMESPACE, + namespace: NS, }, storage: { apiVersion: FORKLIFT_API_VERSION, kind: 'StorageMap', name: storageMapName, - namespace: NAMESPACE, + namespace: NS, }, }, - targetNamespace: TARGET_NAMESPACE, + targetNamespace: targetNamespace.value, vms: vms.value.map((vm) => ({ id: vm.id, name: vm.name || vm.id })), warm: false, }, @@ -177,9 +188,19 @@ const startMigrationAction = async() => { await plan.startMigration(); }; -const init = () => { +const init = async() => { vms.value = props.selectedVms; + const inStore = store.getters['currentProduct'].inStore; + + try { + const namespaces = await store.dispatch(`${ inStore }/findAll`, { type: NAMESPACE }); + + namespaceOptions.value = namespaces.filter((ns) => !ns.isSystem).map((ns) => ns.metadata.name).sort().map((name) => ({ label: name, value: name })); + } catch (e) { + namespaceOptions.value = []; + } + if (props.mappingEntries) { networkMappings.value = (props.mappingEntries.networkEntries || []).map((entry) => ({ source: entry.name || entry.id, @@ -216,9 +237,18 @@ defineExpose({ startMigration: startMigrationAction });