// Copyright 2021 99cloud // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import React from 'react'; import { inject, observer } from 'mobx-react'; import Base from 'components/Form'; import { physicalNodeTypes } from 'resources/nova/instance'; import { Col, Row } from 'antd'; import { getAllDataDisks } from 'resources/cinder/snapshot'; export class ConfirmStep extends Base { init() {} get title() { return 'ConfirmStep'; } get name() { return 'ConfirmStep'; } get enableCinder() { return this.props.rootStore.checkEndpoint('cinder'); } allowed = () => Promise.resolve(); getDisk(diskInfo, bootFromVolume) { if (!bootFromVolume) { return null; } const { size, typeOption, deleteTypeLabel } = diskInfo || {}; return `${typeOption.label} ${size}GiB ${deleteTypeLabel}`; } getBootableVolumeDisk() { const { bootableVolume } = this.props.context; const { size, volume_type } = bootableVolume.selectedRows[0]; return `${volume_type} ${size}GiB`; } getDeleteVolumeInstance() { const { deleteVolumeInstance } = this.props?.context; return deleteVolumeInstance ? t('Yes') : t('No'); } getSystemDisk() { if (!this.enableCinder) return null; const { context } = this.props; const { systemDisk, source: { value } = {}, instanceSnapshotDisk, bootFromVolume = true, } = context; if (value === 'bootableVolume') { return this.getBootableVolumeDisk(); } if (value === 'instanceSnapshot' && instanceSnapshotDisk !== null) { return this.getDisk(instanceSnapshotDisk, bootFromVolume); } return this.getDisk(systemDisk, bootFromVolume); } getDataDisk() { if (!this.enableCinder) return null; const { context } = this.props; const { dataDisk = [], source: { value } = {}, instanceSnapshotDataVolumes = [], } = context; let allDataDisks = dataDisk; if ( value === 'instanceSnapshot' && instanceSnapshotDataVolumes?.length > 0 ) { allDataDisks = getAllDataDisks({ dataDisk, instanceSnapshotDataVolumes }); } return allDataDisks.map((it) => this.getDisk(it.value, true)); } getFlavor() { const { context } = this.props; const { flavor } = context; const { disk, ram, vcpus } = flavor.selectedRows[0]; return disk ? `${vcpus}VCPU/${disk}GiB/${Number.parseInt(ram / 1024, 10)}GiB` : `${vcpus}VCPU/${Number.parseInt(ram / 1024, 10)}GiB`; } getFlavorName() { const { context } = this.props; const { flavor } = context; const { name } = flavor.selectedRows[0]; return name; } getPriceSecond() { const { context } = this.props; const { flavor } = context; const { pricePerSecond } = flavor.selectedRows[0]; return pricePerSecond; } getPriceMonth() { const { context } = this.props; const { flavor } = context; const { pricePerMonth } = flavor.selectedRows[0]; return pricePerMonth; } getSourceValue() { const { context } = this.props; const { source } = context; const { selectedRows = [], selectedRowKeys = [] } = context[source.value]; return selectedRows.length ? selectedRows[0].name : selectedRowKeys[0]; } getVirtualLANs() { const { context } = this.props; const { networks = [] } = context; const values = networks.map((it) => { const { networkOption, subnetOption, ipTypeOption, ip } = it.value; const subnet = ipTypeOption.value === 1 ? subnetOption.name || subnetOption.label : ''; return `${networkOption.name || networkOption.label} ${ ipTypeOption.label } ${subnet} ${ipTypeOption.value === 1 ? ip : ''}`; }); return ( {values.map((i) => ( {i} ))} ); } getPorts() { const { context } = this.props; const { ports: { selectedRows = [] } = {} } = context; const values = selectedRows.map((it) => it.name || it.id); return ( {values.map((i) => ( {i} ))} ); } getSecurityGroups() { const { context } = this.props; const { securityGroup: { selectedRows = [] } = {} } = context; const values = selectedRows.map((it) => it.name); return ( {values.map((i) => ( {i} ))} ); } getLoginType() { const { context } = this.props; const { loginType, keypair } = context; const { value, label } = loginType; return `${label} ${ value === 'keypair' ? keypair.selectedRows[0].name : '' }`; } getPhysicalNode() { const { context } = this.props; const { physicalNodeType, physicalNode } = context; if (!physicalNodeType) { return physicalNodeTypes[0].label; } if (physicalNodeType.value === 'smart') { return physicalNodeType.label; } return physicalNode.selectedRows[0].hypervisor_hostname; } getServerGroup() { const { context } = this.props; const { serverGroup } = context; if (!serverGroup || !serverGroup.selectedRows.length) { return '-'; } return serverGroup.selectedRows[0].name; } getIso() { const { context } = this.props; const { iso } = context; if (!iso || iso.length === 0) { return '-'; } const values = iso.map((it) => it.value); return values.join(' '); } goStep(index) { const { goStep } = this.props; goStep && goStep(index); } get defaultValue() { return {}; } get formItems() { const { context } = this.props; let baseItems = [ // { // label: t('Resource Pool'), // value: context.resource, // }, { label: t('Start Source'), value: context.source.label, }, { label: t('System Disk'), value: this.getSystemDisk(), }, { label: t('Delete Volume on Instance Delete'), value: this.getDeleteVolumeInstance(), key: 'deleteVolume', }, { label: t('Available Zone'), value: context.availableZone.label, }, { label: t('Start Source Name'), value: this.getSourceValue(), }, { label: t('Data Disk'), value: this.getDataDisk(), contentStyle: { display: 'inline-block' }, }, { label: t('Project'), value: context.project, }, { label: t('Flavor'), value: this.getFlavor(), }, ]; if (!this.enableCinder) { baseItems = baseItems.filter( (it) => ![t('System Disk'), t('Data Disk')].includes(it.label) ); } if (context.source.value.toUpperCase() !== 'BOOTABLEVOLUME') { baseItems = baseItems.filter((it) => it?.key !== 'deleteVolume'); } return [ { name: 'confirm-count', label: t('Count'), type: 'label', content: context.count || 1, }, { name: 'confirm-config', label: t('Config Overview'), type: 'descriptions', title: t('Base Config'), onClick: () => { this.goStep(0); }, items: baseItems, }, { type: 'short-divider', }, { name: 'confirm-config-network', label: ' ', type: 'descriptions', title: t('Network Config'), onClick: () => { this.goStep(1); }, items: [ { label: `${t('Virtual LAN')}(${t('New')})`, value: this.getVirtualLANs(), span: 1, }, { label: `${t('Virtual LAN')}(${t('Created')})`, value: this.getPorts(), span: 1, }, { label: t('Security Group'), value: this.getSecurityGroups(), span: 1, }, ], }, { type: 'short-divider', }, { name: 'confirm-config-system', label: ' ', type: 'descriptions', title: t('System Config'), onClick: () => { this.goStep(2); }, items: [ { label: t('Name'), value: context.name, }, { label: t('Login Type'), value: this.getLoginType(), }, { label: t('Physical Node'), value: this.getPhysicalNode(), }, { label: t('Server Group'), value: this.getServerGroup(), }, // { // label: t('Mount ISO'), // value: this.getIso(), // }, ], }, { type: 'short-divider', }, { name: 'Price', label: ' ', type: 'descriptions', title: t('Price'), items: [ { label: t('name'), value: this.getFlavorName(), }, { label: t('Flavor'), value: this.getFlavor(), }, { label: 'Price / second', value: this.getPriceSecond(), }, { label: 'Price / month', value: this.getPriceMonth(), }, ], }, ]; } } export default inject('rootStore')(observer(ConfirmStep));