| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537 |
- import * as R from 'ramda'
- import _ from 'lodash'
- import { mapGetters } from 'vuex'
- import { LOGIN_TYPES_MAP, NETWORK_OPTIONS_MAP, FORECAST_FILTERS_MAP } from '@Compute/constants'
- import OsSelect from '@Compute/sections/OsSelect'
- import ServerPassword from '@Compute/sections/ServerPassword'
- import ServerNetwork from '@Compute/sections/ServerNetwork'
- import SchedPolicy from '@Compute/sections/SchedPolicy'
- import DomainProject from '@/sections/DomainProject'
- import CloudregionZone from '@/sections/CloudregionZone'
- import Tag from '@/sections/Tag'
- import validateForm, { isRequired, isWithinRange } from '@/utils/validate'
- import { IMAGES_TYPE_MAP } from '@/constants/compute'
- import { sizestr } from '@/utils/utils'
- import { WORKFLOW_TYPES } from '@/constants/workflow'
- import i18n from '@/locales'
- import { checkIpV6, getIpv6Start } from '@Compute/utils/createServer'
- import BottomBar from './BottomBar'
- 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 default {
- props: {
- cloudEnv: {
- type: String,
- required: true,
- },
- initFormData: {
- type: Object,
- default: () => ({}),
- },
- isInitForm: {
- type: Boolean,
- default: false,
- },
- },
- components: {
- BottomBar,
- CloudregionZone,
- OsSelect,
- ServerPassword,
- ServerNetwork,
- SchedPolicy,
- DomainProject,
- Tag,
- },
- data () {
- const initData = this.isInitForm && this.initFormData
- const imageTypeInitValue = initData.extraData?.image_type || IMAGES_TYPE_MAP.standard.key
- let initImage = ''
- if (initData.disks) {
- initData.disks.forEach(item => {
- if (item.image_id) {
- initImage = item.image_id
- }
- })
- }
- if (initData.extraData?.image) {
- initImage = initData.extraData.image
- }
- let initLoginType = 'random'
- if (initData.keypair) {
- initLoginType = 'keypair'
- }
- if (initData.hasOwnProperty('reset_password') && !initData.reset_password) {
- initLoginType = 'image'
- }
- if (initData.hasOwnProperty('password') && initData.password) {
- initLoginType = 'password'
- }
- let initNetworkType = NETWORK_OPTIONS_MAP.default.key
- let initBonding = false
- if (initData.nets) {
- if (initData.nets[0] && initData.nets[0].hasOwnProperty('exit') && !initData.nets[0].exit) {
- if (initData.nets[0].require_teaming) {
- initBonding = true
- }
- initNetworkType = NETWORK_OPTIONS_MAP.default.key
- } else if (initData.nets[0] && initData.nets[0].hasOwnProperty('network') && initData.extraData?.extraNets && initData.extraData?.extraNets[0] && initData.extraData?.extraNets[0].hasOwnProperty('network')) {
- initNetworkType = NETWORK_OPTIONS_MAP.manual.key
- if (initData.nets[0].require_teaming) {
- initBonding = true
- }
- } else {
- initNetworkType = NETWORK_OPTIONS_MAP.schedtag.key
- if (initData.nets[0].schedtags && initData.nets[0].schedtags.length && initData.nets[0].schedtags[0].require_teaming) {
- initBonding = true
- }
- }
- }
- let initSchedPolicyType = 'default'
- if (initData.prefer_host) {
- initSchedPolicyType = 'host'
- }
- if (initData.schedtags && initData.schedtags.length) {
- initSchedPolicyType = 'schedtag'
- }
- return {
- submiting: false,
- errors: {},
- formItemLayout: {
- wrapperCol: {
- md: { span: 18 },
- xl: { span: 20 },
- xxl: { span: 22 },
- },
- labelCol: {
- md: { span: 6 },
- xl: { span: 4 },
- xxl: { span: 2 },
- },
- },
- offsetFormItemLayout: {
- wrapperCol: {
- md: { span: 18, offset: 6 },
- xl: { span: 20, offset: 4 },
- xxl: { span: 22, offset: 2 },
- },
- },
- form: {
- fc: this.$form.createForm(this, {
- onValuesChange: (props, values) => {
- this.$bus.$emit('updateForm', values)
- if (values.hasOwnProperty('cloudregion') && values.cloudregion.key) {
- this.cloudregion = values.cloudregion.key
- }
- if (values.hasOwnProperty('zone') && values.zone.key) {
- this.capability(values.zone.key)
- this.zone = values.zone.key
- }
- if (values.hasOwnProperty('imageType')) {
- if (values.imageType === 'iso') {
- this.capability(this.zone, true)
- } else {
- this.capability(this.zone)
- }
- }
- if (values.domain) {
- this.project_domain = values.domain.key
- this.params.region = {
- ...this.params.region,
- project_domain: values.domain.key,
- }
- }
- },
- }),
- fi: {
- capability: {},
- imageMsg: {},
- networkList: [],
- createType: 'baremetal',
- },
- },
- decorators: {
- domain: [
- 'domain',
- {
- initialValue: initData.extraData?.domain_id || this.$route.query.domain_id || '',
- rules: [
- { validator: isRequired(), message: i18n.t('rules.domain'), trigger: 'change' },
- ],
- },
- ],
- project: [
- 'project',
- {
- initialValue: initData.project_id || '',
- rules: [
- { validator: isRequired(), message: i18n.t('rules.project'), trigger: 'change' },
- ],
- },
- ],
- name: [
- 'name',
- {
- initialValue: initData.generate_name || '',
- validateTrigger: 'blur',
- validateFirst: true,
- rules: [
- { required: true, message: i18n.t('compute.text_210') },
- { validator: this.$validate('resourceCreateName') },
- ],
- },
- ],
- regionZone: {
- cloudregion: [
- 'cloudregion',
- {
- initialValue: { key: initData.prefer_region || '', label: '' },
- rules: [
- { required: true, message: i18n.t('compute.text_212') },
- ],
- },
- ],
- zone: [
- 'zone',
- {
- initialValue: { key: initData.prefer_zone || '', label: '' },
- rules: [
- { required: true, message: i18n.t('compute.text_213') },
- ],
- },
- ],
- },
- count: [
- 'count',
- {
- initialValue: initData.count || 1,
- },
- ],
- imageOS: {
- os: [
- 'os',
- {
- initialValue: initData.extraData?.os || '',
- rules: [
- { required: true, message: i18n.t('compute.text_153') },
- ],
- },
- ],
- image: [
- 'image',
- {
- initialValue: { key: initImage || '', label: '' },
- rules: [
- { validator: isRequired(), message: i18n.t('compute.text_214') },
- ],
- },
- ],
- imageType: [
- 'imageType',
- {
- initialValue: imageTypeInitValue,
- },
- ],
- },
- specifications: [
- 'specifications',
- {
- initialValue: initData.extraData?.specifications || '',
- rules: [
- { required: true, message: i18n.t('compute.text_313') },
- ],
- },
- ],
- loginConfig: {
- loginType: [
- 'loginType',
- {
- initialValue: initLoginType,
- },
- ],
- keypair: [
- 'loginKeypair',
- {
- initialValue: initData.keypair || '',
- rules: [
- { required: true, message: i18n.t('compute.text_203') },
- ],
- },
- ],
- password: [
- 'loginPassword',
- {
- initialValue: initData.password || '',
- validateFirst: true,
- rules: [
- { required: true, message: i18n.t('compute.text_204') },
- { validator: validateForm('sshPassword') },
- ],
- },
- ],
- },
- network: {
- networkType: [
- 'networkType',
- {
- initialValue: initNetworkType,
- },
- ],
- 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: this.$t('compute.text_218'),
- }, {
- validator: checkIpInSegment(i, networkData),
- }],
- },
- ],
- ips6: (i, networkData) => [
- `networkIpsAddress6[${i}]`,
- {
- validateFirst: true,
- validateTrigger: ['blur', 'change'],
- rules: [
- {
- required: true,
- message: this.$t('compute.complete_ipv6_address'),
- },
- {
- validator: checkIpV6(i, networkData),
- },
- ],
- },
- ],
- ipv6_mode: (i, networkData) => [
- `networkIPv6Modes[${i}]`,
- {
- initialValue: 'all',
- },
- ],
- ipv6s: (i, networkData) => [
- `networkIPv6s[${i}]`,
- {
- validateFirst: true,
- validateTrigger: ['blur', 'change'],
- },
- ],
- },
- 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('compute.text_123'),
- }],
- },
- ],
- },
- },
- schedPolicy: {
- schedPolicyType: [
- 'schedPolicyType',
- {
- initialValue: initSchedPolicyType,
- },
- ],
- schedPolicyHost: [
- 'schedPolicyHost',
- {
- initialValue: initData.prefer_host,
- rules: [
- { required: true, message: i18n.t('compute.text_314') },
- ],
- },
- ],
- 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('compute.text_123'),
- }],
- },
- ],
- },
- },
- description: [
- 'description',
- ],
- __meta__: [
- '__meta__',
- {
- initialValue: initData.__meta__ || {},
- rules: [
- { validator: validateForm('tagName') },
- ],
- },
- ],
- },
- zone: '',
- cloudregion: '',
- params: {
- zone: {},
- region: {
- usable: true,
- is_on_premise: true,
- scope: this.$store.getters.scope,
- },
- policySchedtag: {
- limit: 1024,
- 'filter.0': 'resource_type.equals(hosts)',
- scope: this.$store.getters.scope,
- },
- policyHostParams: {
- enabled: 1,
- usable: true,
- is_empty: true,
- host_type: 'baremetal',
- scope: this.$store.getters.scope,
- },
- vpcParams: {
- usable: true,
- scope: this.$store.getters.scope,
- // limit: 0,
- // show_emulated: true,
- filter: 'id.equals("default")',
- },
- },
- selectedImage: {},
- specOptions: [],
- selectedSpecItem: {},
- resourceType: 'shared',
- policyHostDisabled: [],
- diskData: {},
- diskOptionsDate: [],
- chartSettings: {
- limitShowNum: 5,
- radius: 50,
- selectedMode: 'single',
- labelLine: {
- normal: {
- show: true,
- },
- },
- label: {
- position: 'inside',
- },
- itemStyle: {
- color: function (params) {
- const colorList = ['#afa3f5', '#00d488', '#3feed4', '#3bafff', '#f1bb4c', 'rgba(250,250,250,0.5)']
- if (params.data.name === i18n.t('compute.text_315')) {
- return '#e3e3e3'
- } else {
- return colorList[params.dataIndex]
- }
- },
- },
- offsetY: 100,
- dataType: function (v) {
- return v + ' G'
- },
- },
- isBonding: initBonding,
- isShowFalseIcon: false,
- count: 1,
- hostData: [],
- filterHostData: [],
- isSupportIso: false,
- project_domain: '',
- projectId: '',
- domainId: '',
- osSelectImageType: 'standard',
- wires: [],
- tagDefaultChecked: {},
- }
- },
- computed: {
- ...mapGetters([
- 'isAdminMode',
- 'scope',
- 'isDomainMode',
- ]),
- routerQuery () {
- return this.$route.query
- },
- policySchedtagParams () {
- const ret = {
- limit: 1024,
- 'filter.0': 'resource_type.equals(hosts)',
- scope: this.$store.getters.scope,
- }
- const zone = this.zone
- if (zone) {
- ret.zone_id = zone
- }
- return ret
- },
- imageParams () {
- return {
- status: 'active',
- details: true,
- limit: 0,
- 'filter.0': 'disk_format.notequals(iso)',
- scope: this.$store.getters.scope,
- is_standard: true,
- }
- },
- networkParam () {
- let ret = {
- zone: this.zone,
- usable: true,
- filter: ['server_type.notin(hostlocal, container)'],
- }
- if (this.isInstallOperationSystem) {
- if (this.$route.query.wire_id) ret.filter = `wire_id.in(${this.$route.query.wire_id})`
- ret = {
- ...ret,
- scope: this.$store.getters.scope,
- host: this.$route.query.host_id,
- }
- return ret
- } else {
- ret = {
- ...ret,
- ...this.scopeParams,
- }
- }
- if (!R.isEmpty(this.wires)) {
- ret.filter.push(`wire_id.in(${this.wires.join(',')})`)
- }
- return ret
- },
- vpcResource () {
- if (this.isInstallOperationSystem) {
- return 'vpcs'
- }
- return `cloudregions/${this.cloudregion}/vpcs`
- },
- scopeParams () {
- if (this.isDomainMode) {
- return {
- scope: this.scope,
- }
- }
- return { project_domain: this.project_domain || this.projectId }
- },
- hasMeterService () { // 是否有计费的服务
- const { services } = this.$store.getters.userInfo
- const meterService = services.find(val => val.type === 'meter')
- if (meterService && meterService.status === true) {
- return true
- }
- return false
- },
- isInstallOperationSystem () { // 是否是安装操作系统
- if (this.$route.query.host_id) {
- return true
- }
- return false
- },
- osSelectTypes () {
- const types = ['standard', 'customize']
- if (this.isInstallOperationSystem && this.isSupportIso) {
- types.push('iso')
- }
- if (!this.isInstallOperationSystem) {
- types.push('iso')
- }
- return types
- },
- isOpenWorkflow () {
- return this.checkWorkflowEnabled(WORKFLOW_TYPES.APPLY_MACHINE)
- },
- isCheckedIso () {
- return this.osSelectImageType === 'iso'
- },
- isWindows () {
- let isWindows = false
- if (this.selectedImage.os && this.form.fd.os.toLowerCase() === 'windows') {
- isWindows = true
- }
- return isWindows
- },
- loginTypes () { // 主机模板隐藏手工输入密码
- const maps = R.clone(LOGIN_TYPES_MAP)
- if (this.isWindows) {
- delete maps.keypair
- }
- const loginTypes = Object.keys(maps)
- return loginTypes
- },
- },
- provide () {
- return {
- form: this.form,
- fi: this.form.fi,
- }
- },
- watch: {
- diskOptionsDate: {
- handler (val) {
- let isDistribution = false
- let isDiff = false // 是否存在不通的raid盘
- for (var i = 0; i < this.diskOptionsDate.length; i++) {
- // 每一项是否有分配磁盘
- if (i > 0) {
- const rowsLength = this.diskOptionsDate[i].chartData.rows.length
- if ((rowsLength === 1 && this.diskOptionsDate[i].chartData.rows[0].name !== i18n.t('compute.text_315')) || (rowsLength > 1)) {
- isDistribution = true
- }
- }
- if (this.diskOptionsDate[0].diskInfo[1] !== this.diskOptionsDate[i].diskInfo[1]) {
- isDiff = true
- }
- if (isDiff && this.diskOptionsDate[0].remainder > 0 && isDistribution) {
- this.isShowFalseIcon = true
- } else {
- this.isShowFalseIcon = false
- }
- }
- },
- deep: true,
- },
- project_domain (newVal, oldVal) {
- if (this.isInstallOperationSystem) this.fetchSpec()
- this.capability(this.zone)
- },
- },
- created () {
- this.zonesM2 = new this.$Manager('zones')
- this.serverM = new this.$Manager('servers')
- this.schedulerM = new this.$Manager('schedulers', 'v1')
- this.fetchSpec = _.debounce(this._fetchSpec, 500)
- if (this.$route.query.id) {
- this.fetchSpec()
- this.hostDetail()
- }
- if (this.$route.query.zone_id) {
- this.zone = this.$route.query.zone_id
- this.capability(this.$route.query.zone_id)
- }
- if (this.scope !== 'project') {
- this.loadHostOpt()
- }
- },
- mounted () {
- this.initForm()
- },
- methods: {
- async getCapability (v, data) { // 可用区查询
- const params = {
- show_emulated: true,
- resource_type: this.resourceType,
- host_type: 'baremetal',
- ...this.scopeParams,
- $t: 1,
- }
- if (this.$store.getters.isAdminMode) {
- params.project_domain = data?.extraData?.domain_id
- }
- return this.zonesM2.get({ id: `${v}/capability`, params })
- },
- async initForm () {
- const initData = this.initFormData
- let cData = {}
- if (this.isInitForm && initData.extraData && this.form?.fc) {
- try {
- const { data: capabilityData } = await this.getCapability(initData.prefer_zone, initData)
- this.form.fi.capability = capabilityData
- cData = capabilityData
- } catch (error) {
- throw error
- }
- this.$nextTick(() => {
- // 初始化磁盘
- if (initData.baremetal_disk_configs && initData.baremetal_disk_configs.length) {
- let diskData = null
- if (initData.extraData?.specifications && cData?.specs?.hosts) {
- const keys = Object.keys(cData.specs.hosts)
- for (const key of keys) {
- if (key.replace(/model:.+\//, '') === initData.extraData?.specifications) {
- diskData = cData.specs.hosts[key].disk
- }
- }
- }
- if (diskData) {
- initData.baremetal_disk_configs.forEach(item => {
- const key = `${item.driver}.adapter${item.adapter}`
- const info = _.get(diskData, key) || []
- if (info.length) {
- const opt1 = `${info[0].type}:${sizestr(info[0].size, 'M', 1024)}`
- this.addDiskCallBack({
- computeCount: item.count, // TODO
- count: item.count,
- start_index: item.range[0],
- end_index: info[0].index,
- option: [`${item.driver}:adapter${item.adapter}`, opt1, item.conf],
- })
- }
- })
- }
- }
- // 初始化网络
- if (this.$refs.networkRef && initData.nets) {
- let initNetworkType = NETWORK_OPTIONS_MAP.default.key
- if (initData.nets[0] && initData.nets[0].hasOwnProperty('exit') && !initData.nets[0].exit) {
- initNetworkType = NETWORK_OPTIONS_MAP.default.key
- } else if (initData.nets[0] && initData.nets[0].hasOwnProperty('network') && initData.extraData?.extraNets && initData.extraData?.extraNets[0] && initData.extraData?.extraNets[0].hasOwnProperty('network')) {
- initNetworkType = NETWORK_OPTIONS_MAP.manual.key
- } else {
- initNetworkType = NETWORK_OPTIONS_MAP.schedtag.key
- }
- this.form.fc.setFieldsValue({
- networkType: initNetworkType,
- })
- this.$refs.networkRef.change({ target: { value: initNetworkType }, name: 'default' })
- if (initNetworkType === NETWORK_OPTIONS_MAP.manual.key) {
- this.$nextTick(() => {
- if (this.$refs.networkRef.$refs.networkConfigRef) {
- this.$refs.networkRef.$refs.networkConfigRef.initData(initData.extraData.extraNets)
- }
- })
- }
- if (initNetworkType === NETWORK_OPTIONS_MAP.schedtag.key) {
- this.$nextTick(() => {
- if (this.$refs.networkRef.$refs.networkSchedtagRef) {
- this.$refs.networkRef.$refs.networkSchedtagRef.initData(initData.nets)
- }
- })
- }
- }
- // 高级配置
- this.$nextTick(() => {
- // 调度策略
- if (this.$refs.schedPolicyRef) {
- if (initData.prefer_host) {
- this.$refs.schedPolicyRef.change({ target: { value: 'host' }, name: 'default' })
- }
- if (initData.schedtags && initData.schedtags.length) {
- this.$refs.schedPolicyRef.change({ target: { value: 'schedtag' }, name: 'default' })
- setTimeout(() => {
- if (this.$refs.schedPolicyRef.$refs.policySchedtagRef) {
- this.$refs.schedPolicyRef.$refs.policySchedtagRef.initData(initData.schedtags)
- }
- }, 1000)
- }
- }
- })
- // 初始化标签
- if (initData.__meta__) {
- const ret = {}
- R.forEachObjIndexed((value, key) => {
- ret[key] = R.is(Array, value) ? value : [value]
- }, initData.__meta__)
- this.tagDefaultChecked = ret
- }
- })
- }
- },
- vpcResourceMapper (list) {
- return list.filter(val => val.id === 'default')
- },
- setSelectedImage ({ imageMsg }) {
- this.selectedImage = imageMsg
- },
- // 过滤network数据
- networkResourceMapper (data) {
- data = data.filter((d) => d.server_type !== 'ipmi' && d.server_type !== 'pxe')
- return data
- },
- // 指定物理机改变
- hostChange (e) {
- this.hostDetail(e)
- },
- // 规格变动
- specificationChange (value) {
- const str = value.replace(/\//g, ',')
- const arr = str.split(',')
- const obj = {}
- for (var i = 0; i < arr.length; i++) {
- const arr2 = arr[i].split(':')
- obj[arr2[0]] = arr2[1]
- }
- this.selectedSpecItem = obj
- const currentSpec = this.form.fi.capability.specs.hosts[value]
- if (R.has('isolated_devices')(currentSpec)) {
- this.selectedSpecItem.isolated_devices = currentSpec.isolated_devices
- }
- this.diskData = this.form.fi.capability.specs.hosts[value].disk
- // 过滤包含此规格的物理机
- this.hostResourceMapper(this.hostData)
- // 获取此规格的包含的wire
- this.getSpecWire(value)
- // 规格变动清空历史硬盘配置
- this.diskOptionsDate = []
- },
- // 获取物理机数据
- loadHostOpt () {
- const manager = new this.$Manager('hosts')
- const params = { ...this.params.policyHostParams }
- manager.list({ params })
- .then(({ data: { data = [] } }) => {
- this.hostData = data
- this.filterHostData = data
- })
- .catch((error) => {
- throw error
- })
- },
- // 如果是安装操作系统--查询物理机详情
- hostDetail (hostId) {
- const hostManager = new this.$Manager('hosts')
- hostManager.get({ id: this.$route.query.id || hostId })
- .then(({ data }) => {
- if (data.ipmi_info && data.ipmi_info.cdrom_boot) {
- this.isSupportIso = true
- } else {
- this.isSupportIso = false
- }
- })
- },
- // 如果有指定物理机的情况下过滤物理机数据
- hostResourceMapper (data) {
- this.filterHostData = data.filter((d) => R.equals(d.spec.disk, this.diskData))
- },
- // 安装操作系统下获取规格
- _fetchSpec () {
- const manager = new this.$Manager('specs')
- const params = { host_type: 'baremetal', filter: `id.equals(${this.$route.query.id})`, ...this.scopeParams }
- manager.rpc({ methodname: 'GetHostSpecs', params }).then(res => {
- const specs = res.data
- this.$set(this.form.fi.capability, 'specs', {
- hosts: specs,
- })
- if (!R.isNil(specs) && !R.isEmpty(specs)) {
- this._loadSpecificationOptions(specs)
- } else {
- this.specOptions = []
- // 清空选中规格
- this.$nextTick(() => {
- this.form.fc.setFieldsValue({ specifications: '' })
- })
- }
- })
- },
- capability (v, isIso = false) { // 可用区查询
- const data = {
- show_emulated: true,
- resource_type: this.resourceType,
- host_type: 'baremetal',
- ...this.scopeParams,
- }
- if (isIso) {
- data.cdrom_boot = true
- }
- // init 虚拟化平台并默认选择第一项
- this.zonesM2.get({
- id: `${v}/capability`,
- params: data,
- }).then(({ data = {} }) => {
- data.hypervisors = Array.from(new Set(data.hypervisors))
- const specs = data.specs.hosts
- // 如果是安装操作系统,只需要拿取public_network_count
- if (this.isInstallOperationSystem) {
- this.form.fi.capability = {
- ...this.form.fi.capability,
- public_network_count: data.public_network_count,
- auto_alloc_network_count: data.auto_alloc_network_count,
- }
- } else {
- this.form.fi.capability = {
- ...data,
- }
- if (!R.isNil(specs) && !R.isEmpty(specs)) {
- this._loadSpecificationOptions(specs)
- } else {
- this.specOptions = []
- // 清空选中规格
- this.$nextTick(() => {
- this.form.fc.setFieldsValue({ specifications: '' })
- })
- }
- }
- })
- },
- _loadSpecificationOptions (data) {
- const specs = {}
- let entries = Object.entries(data)
- entries = entries.map(item => {
- const newKey = item[0].replace(/model:.+\//, '')
- return [newKey, item[1]]
- })
- entries.forEach(item => {
- specs[item[0]] = item[1]
- })
- const options = []
- for (const k in specs) {
- const spec = {
- text: this.__getSpecification(specs[k]),
- value: k,
- }
- options.push(spec)
- }
- this.form.fi.capability.specs.hosts = specs
- this.specOptions = this.__ignoreModel(options)
- if (this.specOptions && this.specOptions.length) {
- // 规格默认选中第一项
- this.$nextTick(() => {
- this.form.fc.setFieldsValue({ specifications: this.specOptions[0].value })
- })
- // 存储选中规格中的信息
- this.diskData = this.form.fi.capability.specs.hosts[this.specOptions[0].value].disk
- this.hostResourceMapper(this.hostData)
- // 根据规格读取wire数据
- this.getSpecWire(this.specOptions[0].value)
- const originalValue = this.specOptions[0].value
- const str = this.specOptions[0].value.replace(/\//g, ',')
- const arr = str.split(',')
- const obj = {}
- for (var i = 0; i < arr.length; i++) {
- const arr2 = arr[i].split(':')
- obj[arr2[0]] = arr2[1]
- }
- obj.value = originalValue
- this.selectedSpecItem = obj
- const currentSpec = this.form.fi.capability.specs.hosts[originalValue]
- if (R.has('isolated_devices')(currentSpec)) {
- this.selectedSpecItem.isolated_devices = currentSpec.isolated_devices
- }
- }
- },
- __getSpecification (spec) {
- const cpu = spec.cpu
- const mem = sizestr(spec.mem, 'M', 1024)
- // 按类型和容量归并磁盘信息
- const disksObj = {}
- _.forEach(spec.disk, function (adapters, driver) {
- _.forEach(adapters, function (disks, adapter) {
- _.forEach(disks, function (disk) {
- disksObj[disk.type] = disksObj[disk.type] || {}
- disksObj[disk.type][disk.size] = disksObj[disk.type][disk.size] || 0
- disksObj[disk.type][disk.size] += disk.count
- })
- })
- })
- // disk string
- let disks = ''
- _.forEach(disksObj, function (caps, d) {
- disks += '_' + d
- const sizes = []
- _.forEach(caps, function (num, cap) {
- sizes.push(sizestr(cap, 'M', 1024) + 'x' + num)
- })
- disks += sizes.join('_')
- })
- // isolated_devices 根据 model 去重并添加count字段
- if (spec.isolated_devices && spec.isolated_devices.length > 0) {
- const gpuList = R.clone(spec.isolated_devices)
- for (let i = 0; i < gpuList.length; i++) {
- gpuList[i].count = 1
- for (let j = i + 1; j < gpuList.length; j++) {
- if (gpuList[i].model === gpuList[j].model) {
- gpuList[i].count++
- gpuList.splice(j, 1)
- }
- }
- }
- // gpu string
- let gpuString = '_'
- gpuList.map(item => {
- gpuString += `${item.model}X${item.count}、`
- })
- gpuString = gpuString.substr(0, gpuString.length - 1)
- return `${cpu}C${mem}${disks}${gpuString}`
- }
- return `${cpu}C${mem}${disks}`
- },
- __ignoreModel (options) {
- options = options.map(item => {
- return {
- text: item.text,
- value: item.value.replace(/model:.+\//, ''),
- }
- })
- return this.uniqueArr(options, 'value')
- },
- uniqueArr (arr, field) {
- if (field) {
- const obj = {}
- arr.forEach(item => {
- if (!obj[item[field]]) {
- obj[item[field]] = item
- }
- })
- const newArr = Object.values(obj)
- return Array.from(new Set(newArr))
- } else {
- return Array.from(new Set(arr))
- }
- },
- // 添加硬盘配置
- addDisk () {
- this.createDialog('BaremetalCreateDiskDialog', {
- title: i18n.t('compute.perform_create'),
- list: this.list,
- diskData: this.diskData,
- diskOptionsDate: this.diskOptionsDate,
- updateData: (data) => {
- this.addDiskCallBack(data)
- },
- })
- },
- _isNoneRaid (raidOpt) {
- return raidOpt === 'none'
- },
- // 添加硬盘配置后的回调
- addDiskCallBack (data) {
- let arr = []
- // data.option format: `["HPSARaid:adapter0", "HDD:279G", "raid10"]`
- data.option.forEach(item => {
- arr = arr.concat(item.split(':'))
- })
- // arr format: `["HPSARaid", "adapter0", "HDD", "279G", "raid10"]`
- const raidOpt = data.option[2]
- const raidType = arr[0]
- const adapter = arr[1]
- const diskType = arr[2]
- const diskSize = arr[3]
- let range = []
- let k = data.start_index
- if (this._isNoneRaid(raidOpt)) {
- range = [data.start_index]
- } else {
- while (k < data.start_index + data.count) {
- range.push(k)
- k++
- }
- }
- let sizeNumber = 0
- let n = 0
- if (diskSize.substr(diskSize.length - 1, 1) === 'T') {
- n = Number(diskSize.substr(0, diskSize.length - 1)) * 1024
- } else {
- n = Number(diskSize.substr(0, diskSize.length - 1))
- }
- if (this._isNoneRaid(raidOpt)) {
- sizeNumber = n
- } else {
- sizeNumber = this.raidUtil(n, raidOpt, data.count)
- }
- const option = {
- title: diskSize + ' ' + diskType + ' X ' + `${raidOpt === 'none' ? 1 : data.count}`,
- size: sizestr(sizeNumber, 'G', 1024),
- unitSize: sizestr(n, 'G', 1024),
- chartData: {
- columns: ['name', 'size'],
- rows: [],
- },
- diskInfo: [raidType, adapter, raidOpt],
- count: this._isNoneRaid(raidOpt) ? 1 : data.count,
- type: diskType,
- range,
- }
- if (this.diskOptionsDate.length === 0) {
- const defaultSize = 30
- const imageDiskSize = this.selectedImage.min_disk / 1024
- if (imageDiskSize >= defaultSize) {
- sizeNumber = sizeNumber - imageDiskSize
- option.chartData.rows.push({ name: i18n.t('compute.text_316'), size: imageDiskSize })
- } else {
- sizeNumber = sizeNumber - defaultSize
- option.chartData.rows.push({ name: '/', size: defaultSize })
- }
- }
- option.remainder = sizeNumber
- option.chartData.rows.push({ name: i18n.t('compute.text_315'), size: sizeNumber })
- this.diskOptionsDate.push(option)
- data.computeCount--
- if (this._isNoneRaid(raidOpt) && data.computeCount > 0) {
- data.start_index += 1
- this.addDiskCallBack(data)
- }
- },
- handleDiskItemRemove (idx) {
- this.diskOptionsDate.splice(idx, 1)
- },
- chartFun (idx) {
- return {
- click: (e, index) => this.handleChartEvents(e, idx),
- }
- },
- handleChartEvents (e, idx) {
- const selectedArea = this.diskOptionsDate[idx].chartData.rows.filter(item => item.name === e.name)
- let nameArr = []
- this.diskOptionsDate.forEach(item => {
- nameArr = nameArr.concat(item.chartData.rows)
- })
- nameArr = nameArr.filter(item => item.name !== i18n.t('compute.text_315'))
- this.createDialog('DiskOptionsUpdateDialog', {
- title: e.name === i18n.t('compute.text_315') ? i18n.t('compute.text_317') : i18n.t('compute.text_318'),
- list: this.list,
- item: this.diskOptionsDate[idx],
- nameArr,
- selectedArea: selectedArea[0],
- updateData: (values) => {
- const updateItem = this.diskOptionsDate[idx].chartData.rows
- if (e.name === i18n.t('compute.text_315')) {
- // 创建新分区
- updateItem.unshift({ name: values.name, size: values.size, format: values.format })
- if (values.size === this.diskOptionsDate[idx].remainder || values.method === 'autoextend') {
- this.diskOptionsDate[idx].remainder = 0
- updateItem.pop()
- return
- }
- this.diskOptionsDate[idx].remainder = this.diskOptionsDate[idx].remainder - values.size
- updateItem[updateItem.length - 1].size = updateItem[updateItem.length - 1].size - values.size
- } else {
- // 更新分区
- let oldSize = 0
- updateItem.forEach(item => {
- if (item.name === e.name) {
- item.name = values.name
- oldSize = item.size
- item.size = values.size
- }
- })
- // 如何剩余比更新的大
- if (this.diskOptionsDate[idx].remainder > values.size) {
- updateItem[updateItem.length - 1].size = updateItem[updateItem.length - 1].size + oldSize - values.size
- this.diskOptionsDate[idx].remainder = this.diskOptionsDate[idx].remainder + oldSize - values.size
- if (updateItem[updateItem.length - 1].name === i18n.t('compute.text_315')) {
- updateItem[updateItem.length - 1].size = this.diskOptionsDate[idx].remainder
- } else {
- updateItem.push({ name: i18n.t('compute.text_315'), size: this.diskOptionsDate[idx].remainder })
- }
- } else {
- if (values.method === 'autoextend') {
- this.diskOptionsDate[idx].remainder = 0
- updateItem.pop()
- return
- }
- this.diskOptionsDate[idx].remainder = (oldSize - values.size) + this.diskOptionsDate[idx].remainder
- if (this.diskOptionsDate[idx].remainder === 0) return
- if (updateItem[updateItem.length - 1].name === i18n.t('compute.text_315')) {
- updateItem[updateItem.length - 1].size = this.diskOptionsDate[idx].remainder
- } else {
- updateItem.push({ name: i18n.t('compute.text_315'), size: this.diskOptionsDate[idx].remainder })
- }
- }
- }
- },
- })
- },
- validateForm () {
- return new Promise((resolve, reject) => {
- this.form.fc.validateFields((err, values) => {
- if (!err) {
- resolve(values)
- } else {
- reject(err)
- }
- })
- })
- },
- // raid计算大小公式
- raidUtil (n, raid, m) {
- let size = 0
- switch (raid) {
- case 'raid0':
- size = n * m
- break
- case 'raid1':
- size = n * m / m
- break
- case 'raid5':
- size = n * (m - 1)
- break
- case 'raid10':
- size = n * m / 2
- break
- }
- return size
- },
- async handleConfirm (e) {
- e.preventDefault()
- const diskConfigs = []
- const values = await this.validateForm()
- const disks = []
- const nets = []
- const extraData = {
- formType: this.cloudEnv,
- __resource_type__: 'baremetal',
- image_type: values.imageType,
- os: values.os,
- image: values.image.key,
- domain_id: values.domain?.key || this.$store.getters.userInfo.projectDomainId,
- specifications: values.specifications,
- extraNets: [],
- }
- // 判断数据盘是否合法
- if (this.diskOptionsDate.length > 0) {
- if (this.isShowFalseIcon) {
- this.$message.error(i18n.t('compute.text_319'))
- throw new Error(i18n.t('compute.text_319'))
- }
- // 将系统盘放置首位
- const systemDisk = this.diskOptionsDate[0].chartData.rows.pop()
- this.diskOptionsDate[0].chartData.rows.unshift(systemDisk)
- for (var i = 0; i < this.diskOptionsDate.length; i++) {
- const rows = this.diskOptionsDate[i].chartData.rows
- const adapter = Number(this.diskOptionsDate[i].diskInfo[1].charAt(this.diskOptionsDate[i].diskInfo[1].length - 1))
- const configOption = {
- conf: this.diskOptionsDate[i].diskInfo[2],
- driver: this.diskOptionsDate[i].diskInfo[0],
- count: this.diskOptionsDate[i].count,
- range: this.diskOptionsDate[i].range,
- adapter,
- type: this.diskOptionsDate[i].type === 'HDD' ? 'rotate' : 'ssd',
- }
- diskConfigs.push(configOption)
- for (var j = 0; j < rows.length; j++) {
- let option = {
- size: rows[j].size * 1024,
- fs: rows[j].format,
- mountpoint: rows[j].name,
- }
- if (i === 0 && j === 0) {
- // 判断是否是iso导入
- if (values.imageType === 'iso') {
- option = {
- size: rows[j].size * 1024,
- }
- } else {
- option = {
- size: rows[j].size * 1024,
- image_id: values.image.key,
- }
- }
- }
- if (j === rows.length - 1) {
- option.size = -1
- if (!rows[j].format) {
- Reflect.deleteProperty(option, 'fs')
- }
- if (rows[j].name === i18n.t('compute.text_315')) {
- Reflect.deleteProperty(option, 'mountpoint')
- }
- }
- disks.push(option)
- }
- }
- // 根据adapter排序diskConfigs
- diskConfigs.sort((a, b) => { return a.adapter - b.adapter })
- }
- if (values.networks) {
- const networks = values.networks
- for (const key in networks) {
- const option = {
- network: networks[key],
- }
- if (!R.isNil(values.networkIps) && !R.isEmpty(values.networkIps)) {
- option.address = values.networkIps[key]
- }
- if (values.networkIPv6s && values.networkIPv6s[key]) {
- option.require_ipv6 = true
- }
- if (values.networkIpsAddress6 && values.networkIpsAddress6[key]) {
- const ipv6Last = values.networkIpsAddress6[key]
- const target = this.form.fi.networkList.filter(item => item.key === key)
- const ipv6First = getIpv6Start(target[0]?.network?.guest_ip6_start)
- option.address6 = ipv6First + ipv6Last
- }
- if (values.networkIPv6Modes && values.networkIPv6Modes[key] === 'only' && option.require_ipv6) {
- option.strict_ipv6 = true
- }
- // 是否启用bonding
- if (this.isBonding) {
- option.require_teaming = true
- if (this.isInstallOperationSystem) option.private = false
- nets.push(option)
- if (values.vpcs && values.vpcs[key]) {
- const extraOption = { ...option, vpc: values.vpcs[key] }
- extraData.extraNets.push(extraOption)
- } else {
- extraData.extraNets.push(option)
- }
- } else {
- nets.push(option)
- if (values.vpcs && values.vpcs[key]) {
- const extraOption = { ...option, vpc: values.vpcs[key] }
- extraData.extraNets.push(extraOption)
- } else {
- extraData.extraNets.push(option)
- }
- }
- }
- } else if (values.networkSchedtags) {
- R.forEachObjIndexed((value, key) => {
- const obj = {
- id: value,
- }
- if (this.isBonding) {
- obj.require_teaming = true
- }
- const strategy = values.networkPolicys[key]
- if (strategy) {
- obj.strategy = strategy
- }
- nets.push({
- schedtags: [obj],
- })
- }, values.networkSchedtags)
- } else {
- // 是否启用bonding
- if (this.isBonding) {
- nets.push({ exit: false, require_teaming: true })
- } else {
- nets.push({ exit: false })
- }
- }
- // 判断是否是安装操作系统
- let params = {
- project_id: this.projectId?.key,
- count: values.count,
- vmem_size: Number(this.selectedSpecItem.mem.substr(0, this.selectedSpecItem.mem.length - 1)),
- vcpu_count: Number(this.selectedSpecItem.cpu),
- generate_name: values.name,
- hypervisor: 'baremetal',
- auto_start: true,
- vdi: 'vnc',
- disks,
- baremetal_disk_configs: diskConfigs,
- nets,
- prefer_host: this.isInstallOperationSystem ? this.$route.query.id : values.schedPolicyHost,
- description: values.description,
- prefer_region: values.cloudregion ? values.cloudregion.key : this.$route.query.region_id,
- prefer_zone: values.zone ? values.zone.key : this.$route.query.zone_id,
- __meta__: values.__meta__,
- }
- if (values.policySchedtagSchedtags) {
- const schedtags = []
- for (const key in values.policySchedtagSchedtags) {
- if (values.policySchedtagSchedtags[key]) {
- schedtags.push({
- id: values.policySchedtagSchedtags[key],
- strategy: values.policySchedtagPolicys[key],
- })
- }
- }
- params.schedtags = schedtags
- }
- if (values.loginPassword) params.password = values.loginPassword
- if (values.loginKeypair) params.keypair = values.loginKeypair.key
- if (values.loginType === 'image') params.reset_password = false
- if (this.selectedSpecItem.isolated_devices) params.isolated_devices = this.selectedSpecItem.isolated_devices
- // 判断是否是iso导入
- if (values.imageType === 'iso') {
- params = {
- ...params,
- cdrom: values.image.key,
- }
- }
- if (this.isInstallOperationSystem) {
- // Reflect.deleteProperty(params, 'project_id')
- this.createBaremetal(params)
- } else {
- if (this.isOpenWorkflow) { // 提交工单
- const workflowParams = {
- ...params,
- extraData,
- }
- const variables = {
- process_definition_key: WORKFLOW_TYPES.APPLY_MACHINE,
- initiator: this.$store.getters.userInfo.id,
- 'server-create-paramter': JSON.stringify(workflowParams),
- project: this.projectId?.key,
- project_domain: this.domainId?.key || this.$store.getters.userInfo.projectDomainId,
- }
- this.doCreateWorkflow(variables, workflowParams)
- } else { // 创建裸金属
- this.doForecast(params)
- }
- }
- },
- // 创建工单
- doCreateWorkflow (variables, params) {
- this.submiting = true
- if (this.$route.query.workflow) {
- new this.$Manager('historic-process-instances', 'v1')
- .update({ id: `${this.$route.query.workflow}/variables`, data: { variables } })
- .then(() => {
- this.submiting = false
- this.$message.success(i18n.t('compute.text_320', [params.name]))
- this.$router.push('/workflow')
- })
- } else {
- new this.$Manager('process-instances', 'v1')
- .create({ data: { variables } })
- .then(() => {
- this.submiting = false
- this.$message.success(i18n.t('compute.text_320', [params.name]))
- this.$router.push('/workflow')
- })
- .catch(() => {
- this.submiting = false
- })
- }
- },
- doForecast (params) {
- this.submiting = true
- this.schedulerM.rpc({ methodname: 'DoForecast', params })
- .then(res => {
- if (res.data.can_create) {
- this.createBaremetal(params)
- } else {
- this.errors = this.getForecastErrors(res.data)
- this.submiting = false
- }
- })
- .catch(err => {
- this.$message.error(i18n.t('compute.text_321', [err]))
- this.submiting = false
- })
- },
- // 创建裸金属
- createBaremetal (data) {
- const { count } = data
- if (count > 1) {
- this.serverM.batchCreate({ data, count })
- .then(res => {
- this.submiting = false
- this.$message.success(i18n.t('compute.text_322'))
- if (this.isInstallOperationSystem) {
- this.$router.push('/physicalmachine')
- } else {
- this.$router.push('/baremetal')
- }
- })
- .catch(() => {
- this.submiting = false
- })
- } else {
- this.serverM.create({ data })
- .then(res => {
- this.submiting = false
- this.$message.success(i18n.t('compute.text_322'))
- if (this.isInstallOperationSystem) {
- this.$router.push('/physicalmachine')
- } else {
- this.$router.push('/baremetal')
- }
- })
- .catch(() => {
- this.submiting = false
- })
- }
- },
- 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.physicalmachine')}【${item.name}】`
- const filterMapItem = FORECAST_FILTERS_MAP[item.filter_name]
- if (filterMapItem) {
- message += filterMapItem
- } else {
- message += this.$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,
- req_count: data.req_count,
- not_allow_reasons: data.not_allow_reasons,
- }
- },
- getSpecWire (currentSpec) {
- const manager = new this.$Manager('specs')
- const params = { host_type: 'baremetal', kind: 'hosts', key: currentSpec, ...this.scopeParams }
- manager.rpc({ methodname: 'GetObjects', params }).then(res => {
- const hosts = res.data || []
- this.wires = []
- for (const host of hosts) {
- let nicInfos = host.nic_info || []
- nicInfos = nicInfos.filter(item => !['ipmi', 'pxe'].includes(item.nic_type) && item.wire_id)
- const wireIds = nicInfos.map(item => item.wire_id)
- const newWireIds = Array.from(new Set(wireIds))
- this.wires = newWireIds
- }
- })
- },
- handleCancel () {
- this.$router.push({ name: 'Baremetal' })
- },
- },
- }
|