| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420 |
- import * as R from 'ramda'
- import _ from 'lodash'
- import ipaddr from 'ipaddr.js'
- import {
- NETWORK_OPTIONS_MAP,
- SERVER_TYPE,
- EIP_TYPES_MAP,
- EIP_CHARGE_TYPES_MAP,
- BILL_TYPES_MAP,
- SCHED_POLICY_OPTIONS_MAP,
- STORAGE_AUTO,
- SECGROUP_OPTIONS_MAP,
- FORECAST_FILTERS_MAP,
- RESOURCE_TYPES_MAP,
- } from '@Compute/constants'
- import { IMAGES_TYPE_MAP, HOST_CPU_ARCHS } from '@/constants/compute'
- import { HYPERVISORS_MAP } from '@/constants'
- import validateForm, { isRequired, isWithinRange } from '@/utils/validate'
- import store from '@/store'
- import i18n from '@/locales'
- import { removeHttp } from '@/utils/url'
- import { diskSupportTypeMedium, getOriginDiskKey } from '@/utils/common/hypervisor'
- export function getIpv6Start (ipv6) {
- try {
- const IPv6 = ipaddr.IPv6.parse(ipv6)
- return IPv6.toNormalizedString().split(':').slice(0, 4).join(':') + ':'
- } catch (err) {
- console.error('IPv6 address is error')
- return ''
- }
- }
- export function ipv6ToHex (ipv6) {
- return ipv6.parts.map(part => part.toString(16).padStart(4, '0')).join('')
- }
- export function checkIpV6 (i, networkData) {
- return (rule, value, cb) => {
- const ipv6First = getIpv6Start(networkData.guest_ip6_start)
- try {
- const ipv6 = ipv6First + value
- const ipAddr = ipaddr.IPv6.parse(ipv6)
- const subnet1Addr = ipaddr.IPv6.parse(networkData.guest_ip6_start)
- const subnet2Addr = ipaddr.IPv6.parse(networkData.guest_ip6_end)
- if (ipAddr.kind() !== 'ipv6') {
- cb(new Error(i18n.t('compute.error_ipv6')))
- }
- const target = ipv6ToHex(ipAddr)
- const start = ipv6ToHex(subnet1Addr)
- const end = ipv6ToHex(subnet2Addr)
- // 检查IP是否在两个子网之间
- if (!((target >= start && target <= end))) {
- cb(new Error(i18n.t('compute.ipv6_within_range')))
- }
- cb()
- } catch (err) {
- cb(new Error(i18n.t('compute.error_ipv6')))
- }
- }
- }
- export function checkIpInSegment (i, networkData) {
- return (rule, value, cb) => {
- const isIn = isWithinRange(value, networkData.guest_ip_start, networkData.guest_ip_end)
- if (isIn) {
- cb()
- } else {
- cb(new Error(i18n.t('compute.text_205')))
- }
- }
- }
- export function diskValidator (rule, value, callback) {
- if (R.isNil(value) || R.isEmpty(value)) {
- return callback(new Error(i18n.t('compute.text_206')))
- }
- if (!value.startsWith('/')) {
- return callback(new Error(i18n.t('compute.text_207')))
- }
- if (value === '/') {
- return callback(new Error(i18n.t('compute.text_208')))
- }
- callback()
- }
- const validateValidPath = (rule, value, callback) => {
- if (value.startsWith('/')) {
- if (value === '/') {
- callback(new Error(i18n.t('compute.repo.mount_point.check_content')))
- } else {
- callback()
- }
- } else {
- callback(new Error(i18n.t('compute.repo.mount_point.check_start')))
- }
- }
- const validateMountNames = (rule, value, callback) => {
- if (value === undefined) {
- callback(new Error(i18n.t('common.tips.select', [i18n.t('compute.repo.storage_statement')])))
- }
- callback()
- }
- export const createVmDecorators = () => {
- const imageTypeInitValue = IMAGES_TYPE_MAP.standard.key
- return {
- domain: [
- 'domain',
- {
- rules: [
- { validator: isRequired(), message: i18n.t('rules.domain'), trigger: 'change' },
- ],
- },
- ],
- project: [
- 'project',
- {
- rules: [
- { validator: isRequired(), message: i18n.t('rules.project'), trigger: 'change' },
- ],
- },
- ],
- name: [
- 'name',
- {
- initialValue: '',
- validateTrigger: 'blur',
- validateFirst: true,
- rules: [
- { required: true, message: i18n.t('compute.text_210') },
- ],
- },
- ],
- description: [
- 'description',
- {
- initialValue: '',
- },
- ],
- count: [
- 'count',
- {
- initialValue: 1,
- rules: [
- { required: true, message: i18n.t('compute.text_211') },
- ],
- },
- ],
- cloudregionZone: {
- cloudregion: [
- 'cloudregion',
- {
- initialValue: { key: '', label: '' },
- rules: [
- { validator: isRequired(), message: i18n.t('compute.text_212') },
- ],
- },
- ],
- zone: [
- 'zone',
- {
- initialValue: { key: '', label: '' },
- rules: [
- { validator: isRequired(), message: i18n.t('compute.text_213') },
- ],
- },
- ],
- },
- imageOS: {
- prefer_manager: [
- 'prefer_manager',
- {
- rules: [
- { required: true, message: i18n.t('compute.text_149') },
- ],
- },
- ],
- os: [
- 'os',
- {
- initialValue: '',
- rules: [
- { required: true, message: i18n.t('compute.text_153') },
- ],
- },
- ],
- image: [
- 'image',
- {
- initialValue: { key: '', label: '' },
- rules: [
- { validator: isRequired(), message: i18n.t('compute.text_214') },
- ],
- },
- ],
- imageType: [
- 'imageType',
- {
- initialValue: imageTypeInitValue,
- },
- ],
- },
- cloudprovider: [
- 'cloudprovider',
- {
- rules: [
- { required: true, message: i18n.t('compute.text_149') },
- ],
- },
- ],
- pci: {
- pciEnable: [
- 'pciEnable',
- {
- valuePropName: 'checked',
- initialValue: false,
- },
- ],
- pciDevType: i => [
- `pciDevType[${i}]`,
- ],
- pciModel: i => [
- `pciModel[${i}]`,
- {
- rules: [
- { required: true, message: i18n.t('compute.text_147') },
- ],
- },
- ],
- pciCount: i => [
- `pciCount[${i}]`,
- {
- initialValue: 1,
- },
- ],
- },
- vcpu: [
- 'vcpu',
- {
- initialValue: 2,
- },
- ],
- vmem: [
- 'vmem',
- {
- initialValue: 2048,
- },
- ],
- sku: [
- 'sku',
- {
- rules: [
- { validator: isRequired(true, 'id'), message: i18n.t('compute.text_216') },
- ],
- },
- ],
- dataDisk: {
- type: i => [
- `dataDiskTypes[${i}]`,
- {
- rules: [
- { validator: isRequired(), message: i18n.t('compute.text_121') },
- ],
- },
- ],
- size: i => [
- `dataDiskSizes[${i}]`,
- {
- rules: [
- { required: true, message: i18n.t('compute.text_122') },
- ],
- },
- ],
- schedtag: i => [
- `dataDiskSchedtags[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_123'),
- }],
- },
- ],
- policy: i => [
- `dataDiskPolicys[${i}]`,
- {
- initialValue: '',
- validateTrigger: ['blur', 'change'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_123'),
- }],
- },
- ],
- snapshot: i => [
- `dataDiskSnapshots[${i}]`,
- {
- validateTrigger: ['blur', 'change'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_124'),
- }],
- },
- ],
- filetype: i => [
- `dataDiskFiletypes[${i}]`,
- {
- validateTrigger: ['blur', 'change'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_125'),
- }],
- },
- ],
- mountPath: i => [
- `dataDiskMountPaths[${i}]`,
- {
- validateTrigger: ['blur', 'change'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_126'),
- }, {
- validator: diskValidator,
- }],
- },
- ],
- storage: i => [
- `dataDiskStorages[${i}]`,
- {
- rules: [{
- required: true,
- message: i18n.t('compute.text_1351'),
- }],
- },
- ],
- iops: i => [
- `dataDiskIops[${i}]`,
- {
- rules: [{
- required: true,
- message: i18n.t('compute.iops_input_tip'),
- }],
- },
- ],
- throughput: i => [
- `dataDiskThroughputs[${i}]`,
- {
- rules: [{
- required: true,
- message: i18n.t('compute.throughput_input_tip'),
- }],
- },
- ],
- preallocation: i => [
- `dataDiskPreallocation[${i}]`,
- ],
- },
- network: {
- networkType: [
- 'networkType',
- {
- initialValue: NETWORK_OPTIONS_MAP.default.key,
- },
- ],
- networkConfig: {
- vpcs: i => [
- `vpcs[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_194'),
- }],
- },
- ],
- networks: i => [
- `networks[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_217'),
- }],
- },
- ],
- ips: (i, networkData) => [
- `networkIps[${i}]`,
- {
- validateFirst: true,
- validateTrigger: ['blur', 'change'],
- rules: [
- {
- required: true,
- message: i18n.t('compute.text_218'),
- },
- {
- validator: validateForm('IPv4'),
- },
- {
- validator: checkIpInSegment(i, networkData),
- },
- ],
- },
- ],
- macs: (i, networkData) => [
- `networkMacs[${i}]`,
- {
- validateFirst: true,
- validateTrigger: ['blur', 'change'],
- rules: [
- {
- required: true,
- message: i18n.t('compute.text_806'),
- },
- {
- validator: validateForm('mac'),
- },
- ],
- },
- ],
- ips6: (i, networkData) => [
- `networkIpsAddress6[${i}]`,
- {
- validateFirst: true,
- validateTrigger: ['blur', 'change'],
- rules: [
- {
- required: true,
- message: i18n.t('compute.complete_ipv6_address'),
- },
- {
- validator: checkIpV6(i, networkData),
- },
- ],
- },
- ],
- ipv6_mode: (i, networkData) => [
- `networkIPv6Modes[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- },
- ],
- ipv6s: (i, networkData) => [
- `networkIPv6s[${i}]`,
- {
- validateFirst: true,
- validateTrigger: ['blur', 'change'],
- },
- ],
- devices: i => [
- `networkDevices[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.sriov_device_tips'),
- }],
- },
- ],
- },
- networkSchedtag: {
- schedtags: i => [
- `networkSchedtags[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_123'),
- }],
- },
- ],
- policys: (i, networkData) => [
- `networkPolicys[${i}]`,
- {
- validateTrigger: ['blur', 'change'],
- rules: [{
- required: true,
- message: i18n.t('common_256'),
- }],
- },
- ],
- devices: i => [
- `networkDevices[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.sriov_device_tips'),
- }],
- },
- ],
- },
- },
- schedPolicy: {
- schedPolicyType: [
- 'schedPolicyType',
- {
- initialValue: 'default',
- },
- ],
- schedPolicyHost: [
- 'schedPolicyHost',
- {
- rules: [
- { required: true, message: i18n.t('compute.text_219') },
- ],
- },
- ],
- policySchedtag: {
- schedtags: i => [
- `policySchedtagSchedtags[${i}]`,
- {
- validateTrigger: ['change', 'blur'],
- rules: [{
- required: true,
- message: i18n.t('compute.text_123'),
- }],
- },
- ],
- policys: (i, networkData) => [
- `policySchedtagPolicys[${i}]`,
- {
- validateTrigger: ['blur', 'change'],
- rules: [{
- required: true,
- message: i18n.t('common_256'),
- }],
- },
- ],
- },
- },
- duration: {
- durationStandard: [
- 'durationStandard',
- {
- initialValue: 'none',
- },
- ],
- duration: [
- 'duration',
- {
- initialValue: '1h',
- },
- ],
- },
- groups: {
- groupsEnable: [
- 'groupsEnable',
- {
- valuePropName: 'checked',
- initialValue: false,
- },
- ],
- groups: [
- 'groups',
- ],
- },
- bill: {
- billType: [
- 'billType',
- {
- initialValue: 'quantity',
- },
- ],
- duration: [
- 'duration',
- {
- initialValue: '1M',
- },
- ],
- autoRenew: [
- 'autoRenew',
- {
- valuePropName: 'checked',
- },
- ],
- },
- resourceType: [
- 'resourceType',
- {
- preserve: true,
- initialValue: RESOURCE_TYPES_MAP.shared.key,
- },
- ],
- eip: {
- type: [
- 'eip_type',
- {
- initialValue: 'none',
- },
- ],
- charge_type: [
- 'eip_charge_type',
- ],
- bgp_type: [
- 'eip_bgp_type',
- {
- initialValue: '',
- },
- ],
- bandwidth: [
- 'eip_bw',
- {
- initialValue: 30,
- },
- ],
- eip: [
- 'eip',
- {
- rules: [
- { required: true, message: i18n.t('compute.text_145') },
- ],
- },
- ],
- },
- secgroup: {
- type: [
- 'secgroup_type',
- {
- initialValue: 'default',
- },
- ],
- secgroup: [
- 'secgroup',
- {
- validateFirst: true,
- rules: [
- { required: true, message: i18n.t('compute.text_190') },
- ],
- },
- ],
- },
- tag: [
- 'tag',
- {
- rules: [
- { validator: validateForm('tagName') },
- ],
- },
- ],
- os_arch: [
- 'os_arch',
- {
- rules: [
- { required: true, message: i18n.t('compute.text_1363') },
- ],
- },
- ],
- hostName: [
- 'hostName',
- ],
- portMapping: {
- key: i => [
- `containerPorts[${i}]`,
- {
- rules: [
- { required: true, message: i18n.t('common.tips.input', [i18n.t('compute.repo.container_port')]) },
- ],
- },
- ],
- value: i => [
- `hostPorts[${i}]`,
- ],
- },
- containers: {
- name: i => [
- `containerNames[${i}]`,
- {
- rules: [
- { required: true, message: `${i18n.t('common.placeholder')}${i18n.t('common.name')}` },
- { validator: validateForm('k8sLabel') },
- ],
- },
- ],
- source: i => [
- `containerSources[${i}]`,
- {
- initialValue: 'custom',
- },
- ],
- registryImage: i => [
- `registryImages[${i}]`,
- {
- rules: [
- { required: true, message: i18n.t('common.tips.select', [i18n.t('compute.eci.repo.image.registry')]) },
- ],
- },
- ],
- imageCredentialId: i => [
- `imageCredentialIds[${i}]`,
- ],
- image: i => [
- `containerimages[${i}]`,
- {
- rules: [
- { required: true, message: `${i18n.t('common.placeholder')}${i18n.t('compute.repo.container_image')}` },
- ],
- },
- ],
- cpu: i => [
- `containerCpus[${i}]`,
- ],
- memory: i => [
- `containerMemorys[${i}]`,
- ],
- command: i => [
- `containerCommands[${i}]`,
- ],
- arg: i => [
- `containerArgs[${i}]`,
- ],
- volumeMount: i => ({
- key: j => [
- `containerVolumeMountNames[${i}][${j}]`,
- {
- rules: [
- { validator: validateMountNames, trigger: 'blur' },
- ],
- },
- ],
- value: j => [
- `containerVolumeMountPaths[${i}][${j}]`,
- {
- rules: [
- { required: true, message: i18n.t('common.tips.input', []) },
- { validator: validateValidPath, trigger: 'blur' },
- ],
- },
- ],
- }),
- env: i => ({
- key: j => [
- `containerEnvNames[${i}][${j}]`,
- {
- rules: [
- { required: true, message: i18n.t('common.tips.input', [i18n.t('compute.repo.variables')]) },
- ],
- },
- ],
- value: j => [
- `containerEnvValues[${i}][${j}]`,
- {
- rules: [
- { required: true, message: i18n.t('common.tips.input', [i18n.t('compute.repo.value')]) },
- ],
- },
- ],
- }),
- privileged: i => [
- `containerPrivilegeds[${i}]`,
- {
- valuePropName: 'checked',
- initialValue: false,
- },
- ],
- },
- }
- }
- export class Decorator {
- decorators = {}
- // eslint-disable-next-line
- constructor(type) {
- this.type = type
- }
- createDecorators () {
- return createVmDecorators(this.type)
- }
- }
- /**
- * 根据表单拼装创建参数
- *
- * @export
- * @class GenCreateData
- */
- export class GenCreateData {
- // eslint-disable-next-line
- constructor(fd, fi) {
- if (R.isNil(fd)) return
- this.fd = fd
- this.fi = fi
- this.createType = this.fi.createType
- this.isIDC = this.createType === SERVER_TYPE.idc
- this.isPrepaid = this.fd.resourceType === RESOURCE_TYPES_MAP.prepaid.key
- }
- /**
- * 拼装磁盘数据
- *
- * @param { Object } item // 磁盘数据
- * @param { String } type // 磁盘类型 sys | data
- * @param { Number } index // 序号
- * @returns { Object }
- * @memberof GenCreateData
- */
- genDisk (item, type, index) {
- const ret = {
- disk_type: type,
- index,
- backend: item.type === STORAGE_AUTO.key ? '' : item.type,
- size: item.size * 1024,
- format: 'raw',
- fs: 'ext4',
- }
- if (type === 'sys' && this.fd.imageType === IMAGES_TYPE_MAP.iso.key && this.isWindows()) {
- ret.driver = 'ide'
- }
- if (item.medium) {
- ret.medium = item.medium
- }
- if (item.schedtags) {
- ret.schedtags = item.schedtags
- }
- if (item.filetype) {
- ret.fs = item.filetype
- if (item.filetype !== 'swap') {
- ret.mountpoint = item.mountpoint
- }
- }
- if (item.storage_id) {
- ret.storage_id = item.storage_id
- }
- if (item.iops) {
- ret.iops = item.iops
- }
- if (item.throughput) {
- ret.throughput = item.throughput
- }
- if (item.preallocation) {
- ret.preallocation = item.preallocation
- }
- // 磁盘区分介质
- if (diskSupportTypeMedium(this.fd.hypervisor)) {
- ret.backend = getOriginDiskKey(ret.backend)
- }
- return ret
- }
- isWindows () {
- let isWindows = false
- const osType = (_.get(this.fi, 'imageMsg.info.properties.os_type') || '').toLowerCase()
- const os = (_.get(this.fd, 'os') || '').toLowerCase()
- if (~[osType, os].indexOf('windows')) {
- isWindows = true
- }
- return isWindows
- }
- _getDataDiskType (dataDiskTypes) {
- if (!R.isNil(dataDiskTypes) && !R.isEmpty(dataDiskTypes)) {
- const firstKey = Object.keys(dataDiskTypes)[0]
- if (firstKey && dataDiskTypes[firstKey]) {
- return dataDiskTypes[firstKey].key
- }
- }
- }
- _genDisksArr () {
- const dataDiskType = this._getDataDiskType(this.fd.dataDiskTypes)
- const dataDisk = []
- R.forEachObjIndexed((value, key) => {
- const diskObj = {
- size: value,
- type: dataDiskType,
- }
- if (this.fd.dataDiskFiletypes && this.fd.dataDiskFiletypes[key]) {
- diskObj.filetype = this.fd.dataDiskFiletypes[key]
- }
- if (this.fd.dataDiskMountPaths && this.fd.dataDiskMountPaths[key]) {
- diskObj.mountpoint = this.fd.dataDiskMountPaths[key]
- }
- if (this.fd.dataDiskSnapshots && this.fd.dataDiskSnapshots[key]) {
- diskObj.snapshot_id = this.fd.dataDiskSnapshots[key]
- }
- if (this.fd.dataDiskSchedtags && this.fd.dataDiskSchedtags[key]) {
- diskObj.schedtags = [
- { id: this.fd.dataDiskSchedtags[key] },
- ]
- if (this.fd.dataDiskPolicys && this.fd.dataDiskPolicys[key]) {
- diskObj.schedtags[0].strategy = this.fd.dataDiskPolicys[key]
- }
- }
- if (this.fd.dataDiskStorages && this.fd.dataDiskStorages[key]) {
- // if system disk specifies storage, the data disks should do the same
- diskObj.storage_id = this.fd.dataDiskStorages[key] || this.fd.systemDiskStorage
- }
- if (this.fd.dataDiskIops && this.fd.dataDiskIops[key]) {
- diskObj.iops = this.fd.dataDiskIops[key]
- }
- if (this.fd.dataDiskThroughputs && this.fd.dataDiskThroughputs[key]) {
- diskObj.throughput = this.fd.dataDiskThroughputs[key]
- }
- if (this.fi.dataDiskMedium) {
- diskObj.medium = this.fi.dataDiskMedium
- }
- if (this.fd.dataDiskPreallocation && this.fd.dataDiskPreallocation[key]) {
- diskObj.preallocation = this.fd.dataDiskPreallocation[key]
- }
- dataDisk.push(diskObj)
- }, this.fd.dataDiskSizes)
- const disks = { data: dataDisk }
- return disks
- }
- /**
- * 组装所有磁盘数据,数据盘
- *
- * @returns { Array }
- * @memberof GenCreateData
- */
- genDisks () {
- const disks = this._genDisksArr()
- if (this.isPublic && this.isPrepaid) {
- return this.fd.spec.disks
- }
- const ret = []
- for (let i = 0, len = disks.data.length; i < len; i++) {
- ret.push(this.genDisk(disks.data[i], 'data', i + 1))
- }
- return ret
- }
- /**
- * 组装所有网络数据
- *
- * @returns { Array }
- * @memberof GenCreateData
- */
- getPortMappings () {
- const port_mappings = []
- if (this.fd.containerPorts) {
- for (const k in this.fd.containerPorts) {
- const pm = {}
- if (this.fd.containerPorts[k]) {
- pm.port = this.fd.containerPorts[k]
- }
- if (this.fd.hostPorts[k]) {
- pm.host_port = this.fd.hostPorts[k]
- }
- if (pm) {
- port_mappings.push(pm)
- }
- }
- }
- return port_mappings
- }
- genNetworks () {
- let ret = [{ exit: false }]
- // 指定 IP 子网
- if (this.fd.networkType === NETWORK_OPTIONS_MAP.manual.key) {
- ret = []
- R.forEachObjIndexed((value, key) => {
- const obj = {
- network: value,
- }
- if (this.fd.networkIps) {
- const address = this.fd.networkIps[key]
- if (address) {
- obj.address = address
- }
- }
- if (this.fd.networkMacs) {
- const mac = this.fd.networkMacs[key]
- if (mac) {
- obj.mac = mac
- }
- }
- if (this.fd.networkExits) {
- const exit = this.fd.networkExits[key]
- if (exit) {
- obj.exit = true
- }
- }
- if (this.fd.networkIPv6s) {
- const ipv6 = this.fd.networkIPv6s[key]
- if (ipv6) {
- obj.require_ipv6 = true
- }
- }
- const target = this.fi.networkList.filter(item => item.key === key)
- if (this.fd.networkIpsAddress6) {
- const ipv6Last = this.fd.networkIpsAddress6[key]
- const ipv6First = getIpv6Start(target[0]?.network?.guest_ip6_start)
- obj.address6 = ipv6First + ipv6Last
- }
- if (obj.require_ipv6) {
- if (this.fd.networkIPv6Modes && this.fd.networkIPv6Modes[key] === 'only') {
- obj.strict_ipv6 = true
- }
- }
- if (!target[0]?.network?.guest_ip_start && !target[0]?.network?.guest_ip_end && target[0]?.network?.guest_ip6_start) {
- obj.strict_ipv6 = true
- }
- if (this.fd.networkDevices) {
- const device = this.fd.networkDevices[key]
- if (device) {
- obj.sriov_device = { model: device }
- }
- }
- const portMappings = this.getPortMappings()
- if (portMappings.length > 0) {
- obj.port_mappings = portMappings
- }
- ret.push(obj)
- }, this.fd.networks)
- }
- // 指定 调度标签
- if (this.fd.networkType === NETWORK_OPTIONS_MAP.schedtag.key) {
- ret = []
- R.forEachObjIndexed((value, key) => {
- const obj = {
- id: value,
- }
- const strategy = this.fd.networkPolicys[key]
- if (strategy) {
- obj.strategy = strategy
- }
- if (this.fd.networkDevices) {
- const device = this.fd.networkDevices[key]
- if (device) {
- obj.sriov_device = { model: device }
- }
- }
- ret.push({
- schedtags: [obj],
- })
- }, this.fd.networkSchedtags)
- }
- return ret
- }
- /**
- * 获取配置的PCI数据
- *
- * @returns { Array }
- * @memberof GenCreateData
- */
- genPciDevices () {
- const ret = []
- const { pciCount, pciModel } = this.fd
- const pciKeys = Object.keys(this.fd.pciCount)
- pciKeys.forEach(key => {
- for (let i = 0, len = pciCount[key]; i < len; i++) {
- const regexp = /vendor=(.+):(.+)/
- const matched = pciModel[key].match(regexp)
- const model = matched[2]
- const vendor = matched[1]
- ret.push({
- model,
- vendor,
- })
- }
- })
- return ret
- }
- /**
- * 获取调度策略所提交的 key 与 value
- *
- * @returns
- * @memberof GenCreateData
- */
- getSchedPolicyValueKey () {
- const ret = {}
- // 调度策略选择为 指定宿主机
- if (this.fd.schedPolicyType === SCHED_POLICY_OPTIONS_MAP.host.key) {
- if (this.isPublic) {
- ret.key = 'prefer_manager'
- } else {
- ret.key = 'prefer_host'
- }
- ret.value = this.fd.schedPolicyHost
- } else if (this.showPreferManager()) { // 如果是通过云账号过滤镜像
- ret.key = 'prefer_manager'
- ret.value = this.fd.prefer_manager
- }
- // 调度策略选择为 调度标签
- if (this.fd.schedPolicyType === SCHED_POLICY_OPTIONS_MAP.schedtag.key) {
- ret.key = 'schedtags'
- ret.value = []
- R.forEachObjIndexed((value, key) => {
- const item = { id: value }
- if (this.fd.policySchedtagPolicys[key]) {
- item.strategy = this.fd.policySchedtagPolicys[key]
- }
- ret.value.push(item)
- }, this.fd.policySchedtagSchedtags)
- }
- return ret
- }
- /**
- * 获取平台
- *
- * @returns { String }
- * @memberof GenCreateData
- */
- getHypervisor () {
- return HYPERVISORS_MAP.pod.key
- }
- /**
- * 是否是通过云账号过滤后选择的镜像
- *
- * @returns { String }
- * @memberof GenCreateData
- */
- showPreferManager () {
- const imageMsg = IMAGES_TYPE_MAP[this.fd.imageType]
- return imageMsg && imageMsg.enable_cloudaccount
- }
- /**
- * 获取Region
- *
- * @returns { String }
- * @memberof GenCreateData
- */
- getPreferRegion () {
- if (this.isPublic && !this.isPrepaid) {
- return this.fd.sku.cloudregion_id
- }
- return this.fd.cloudregion.key
- }
- /**
- * 获取Zone
- *
- * @returns { String }
- * @memberof GenCreateData
- */
- getPreferZone () {
- let ret = ''
- if (R.is(Object, this.fd.zone)) {
- ret = this.fd.zone.key
- }
- if (R.is(String, this.fd.zone)) { // 字符串形式是公有云 AreaSelect 的 zone
- ret = this.fd.zone
- }
- return ret
- }
- /**
- * 获取CPU核数
- *
- * @returns { String }
- * @memberof GenCreateData
- */
- getCpuCount () {
- let ret = this.fd.vcpu
- if (this.isPublic && this.isPrepaid) {
- ret = this.fd.spec.vcpu_count
- }
- return ret
- }
- /**
- * 获取CPU插槽数
- * @returns
- */
- getCpuSockets () {
- return this.fi.cpuSockets
- }
- /**
- * 获取内存
- *
- * @returns { String }
- * @memberof GenCreateData
- */
- getMemSize () {
- let ret = this.fd.vmem
- if (this.isPublic && this.isPrepaid) {
- ret = this.fd.spec.vmem_size * 1024
- }
- return ret
- }
- getPreferManagerId () {
- let prefer_manager_id = ''
- const hypervisor = this.getHypervisor()
- const privateHypervisors = [HYPERVISORS_MAP.hcso.key, HYPERVISORS_MAP.hcs.key]
- if (this.isPublic || privateHypervisors.includes(hypervisor)) {
- prefer_manager_id = this.fd.cloudprovider
- }
- return prefer_manager_id
- }
- generatePod () {
- const tabKeys = this.fi.containerPanes.map(v => v.key)
- const getEnvs = (names, values) => {
- const envs = []
- if (names) {
- for (const k in names) {
- envs.push({ key: names[k], value: values[k] })
- }
- }
- return envs
- }
- const getVolumeMounts = (names, paths) => {
- const volume_mounts = []
- if (names) {
- for (const k in names) {
- volume_mounts.push({
- type: 'disk',
- disk: {
- index: names[k],
- },
- mount_path: paths[k],
- })
- }
- }
- return volume_mounts
- }
- const containers = tabKeys.map(k => {
- const pciDevices = (this.fd.pciEnable && this.genPciDevices()) || []
- const image = this.fd.registryImages?.[k] || ''
- const credentialId = this.fd.imageCredentialIds?.[k] || ''
- const spec = {
- name: this.fd.containerNames?.[k],
- image: removeHttp(image) || this.fd.containerimages?.[k],
- command: this.fd.containerCommands?.[k]?.split(' '),
- args: this.fd.containerArgs?.[k]?.split(' '),
- privileged: this.fd.containerPrivilegeds?.[k],
- devices: pciDevices.map((item, idx) => {
- return {
- type: 'isolated_device',
- isolated_device: {
- index: idx,
- },
- }
- }),
- envs: getEnvs(this.fd.containerEnvNames?.[k], this.fd.containerEnvValues?.[k]),
- volume_mounts: getVolumeMounts(this.fd.containerVolumeMountNames?.[k], this.fd.containerVolumeMountPaths?.[k]),
- }
- if (credentialId) {
- spec.image_credential_id = credentialId
- }
- return spec
- })
- return {
- containers,
- // port_mappings: getPortMappings(),
- }
- }
- /**
- * 组装所有的创建数据
- *
- * @returns { Object }
- * @memberof GenCreateData
- */
- all () {
- const { create_server_auto_start = true } = store.getters.globalSetting.value || {}
- const data = {
- auto_start: create_server_auto_start,
- generate_name: this.fd.name && this.fd.name.trim(),
- description: this.fd.description,
- hypervisor: this.getHypervisor(),
- __count__: this.fd.count,
- disks: this.genDisks(),
- nets: this.genNetworks(),
- prefer_region: this.getPreferRegion(),
- vcpu_count: this.getCpuCount(),
- vmem_size: this.getMemSize(),
- project_id: (this.fd.project && this.fd.project.key) || store.getters.userInfo.projectId,
- os_arch: _.get(HOST_CPU_ARCHS, `[${this.fd.os_arch}].key`),
- hostname: this.fd.hostName,
- }
- // 非预付费资源池不会添加sku
- if (!this.isPrepaid) {
- data.sku = this.fd.sku.name
- }
- // 弹性IP
- if (this.fd.eip_type === EIP_TYPES_MAP.new.key || this.fd.eip_type === EIP_TYPES_MAP.public.key) {
- if (
- this.fd.eip_charge_type === EIP_CHARGE_TYPES_MAP.traffic.key ||
- this.fd.eip_charge_type === EIP_CHARGE_TYPES_MAP.bandwidth.key
- ) {
- if (this.fd.eip_type === EIP_TYPES_MAP.public.key) {
- data.public_ip_charge_type = this.fd.eip_charge_type
- data.public_ip_bw = this.fd.eip_bw
- } else {
- data.eip_charge_type = this.fd.eip_charge_type
- data.eip_bw = this.fd.eip_bw
- }
- }
- }
- if (this.fd.eip_type === EIP_TYPES_MAP.bind.key) {
- data.eip = this.fd.eip
- }
- // 包年包月参数
- if (this.fd.billType === BILL_TYPES_MAP.package.key) {
- data.duration = this.fd.duration
- // 自动续费
- data.auto_renew = this.fd.autoRenew
- }
- // 线路类型
- if (this.fd.eip_bgp_type) {
- data.eip_bgp_type = this.fd.eip_bgp_type
- }
- // pci
- if (this.fd.pciEnable) {
- data.isolated_devices = this.genPciDevices()
- }
- // 安全组
- if (this.fd.secgroup_type && this.fd.secgroup_type === SECGROUP_OPTIONS_MAP.bind.key) {
- data.secgroups = this.fd.secgroup
- }
- // 如果设置了调度策略则拼装调度所需数据 或者 通过云账号过滤镜像
- if ((this.fd.schedPolicyType !== SCHED_POLICY_OPTIONS_MAP.default.key) || this.showPreferManager()) {
- const schedPolicyValueKey = this.getSchedPolicyValueKey()
- data[schedPolicyValueKey.key] = schedPolicyValueKey.value
- }
- // zone
- const zoneId = this.getPreferZone()
- if (zoneId) {
- data.prefer_zone = zoneId
- }
- const prefer_manager_id = this.getPreferManagerId()
- if (prefer_manager_id) {
- data.prefer_manager_id = prefer_manager_id
- }
- // 到期释放
- if (this.fd.billType !== BILL_TYPES_MAP.package.key && this.fd.durationStandard !== 'none') {
- if (this.fd.durationStandard === 'custom') {
- data.duration = this.fd.duration
- } else {
- data.duration = this.fd.durationStandard
- }
- data.billing_type = 'postpaid'
- }
- // 镜像类型为 iso 需要加参数 cdrom
- if (this.fd.imageType === IMAGES_TYPE_MAP.iso.key || this.fd.imageType === IMAGES_TYPE_MAP.private_iso.key) {
- data.cdrom = this.fd.image.key
- }
- // 主机镜像需要guest image id参数,并且把磁盘中的镜像ID回填回去
- if (this.fd.imageType === IMAGES_TYPE_MAP.host.key) {
- data.guest_image_id = this.fd.image.key
- data.disks.forEach((val, i) => {
- if (this.fi.imageMsg.data_images && i < this.fi.imageMsg.data_images.length) {
- data.disks[i] = { ...val, image_id: this.fi.imageMsg.data_images[i].id }
- }
- })
- }
- // 主机快照需要instance_snapshot_id参数
- if (this.fd.imageType === IMAGES_TYPE_MAP.snapshot.key) {
- data.instance_snapshot_id = this.fd.image.key
- delete data.disks // 主机快照不需要 disks 字段
- } else if (this.fd.imageType === IMAGES_TYPE_MAP.backup.key) {
- data.instance_backup_id = this.fd.image.key
- // delete data.disks // 主机备份可以保留 disks 字段
- }
- // 主机组
- if (this.fd.groupsEnable && this.fd.groups && this.fd.groups.length) {
- data.groups = this.fd.groups
- }
- // 标签
- if (this.fd.tag) {
- data.__meta__ = this.fd.tag
- }
- // 插槽数
- if (this.fi.showCpuSockets) {
- data.cpu_sockets = this.getCpuSockets()
- }
- // 容器
- data.pod = this.generatePod(data)
- return data
- }
- /**
- * 获取创建预测的错误信息
- *
- * @returns { Array }
- * @memberof GenCreateData
- */
- getForecastErrors (data) {
- const errors = []
- if (data.filtered_candidates && data.filtered_candidates.length > 0) {
- for (let i = 0, len = data.filtered_candidates.length; i < len; i++) {
- const item = data.filtered_candidates[i]
- let message = `${i18n.t('dictionary.host')}【${item.name}】`
- const filterMapItem = FORECAST_FILTERS_MAP[item.filter_name]
- if (filterMapItem) {
- message += filterMapItem
- } else {
- message += i18n.t('compute.text_1325', [item.filter_name])
- }
- errors.push({
- message,
- children: item.reasons,
- })
- }
- } else {
- errors.push({
- message: i18n.t('compute.text_227'),
- })
- }
- return {
- errors,
- allow_count: data.allow_count || 0,
- req_count: data.req_count || 1,
- not_allow_reasons: data.not_allow_reasons,
- }
- }
- }
|