feat: 裸金属列表/修改/创建
parent
e01feb840d
commit
e5551d64a9
|
@ -2091,29 +2091,73 @@ export function physicalLineProider(value) {
|
||||||
}
|
}
|
||||||
return obj[value]
|
return obj[value]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bareMetalState(value, type) {
|
export function bareMetalState(value, type) {
|
||||||
const obj = {
|
const obj = {
|
||||||
RUNNING: '运行中',
|
RUNNING: '运行中',
|
||||||
STOPPING: '关机中',
|
STOPPING: '关机中',
|
||||||
|
CREATING: '创建中',
|
||||||
STOPPED: '已关机',
|
STOPPED: '已关机',
|
||||||
STARTING: '开机中',
|
STARTING: '开机中',
|
||||||
REBOOTING: '重启中',
|
REBOOTING: '重启中',
|
||||||
PENDING: '生产中',
|
PENDING: '生产中',
|
||||||
CREATE_FAILED: '创建失败'
|
CREATE_FAILED: '创建失败',
|
||||||
|
RESIZING: '变配中',
|
||||||
|
VERIFY_RESIZE: '确认变配中',
|
||||||
|
RESTARTING: '正在重启',
|
||||||
|
WAITING: '等待其他资源创建中',
|
||||||
|
DELETING: '退订中',
|
||||||
|
DELETE: '退订完成',
|
||||||
|
ERROR: '异常',
|
||||||
|
EXPIRED: '已过期',
|
||||||
|
REBUILD: '重装中',
|
||||||
|
CREATING_IMAGE: '创建镜像中',
|
||||||
|
SUSPENDED: '挂起',
|
||||||
|
SUSPENDING: '挂起中',
|
||||||
|
MIGRATING: '迁移中',
|
||||||
|
BUILD_BACKUP: '创建备份中',
|
||||||
|
EXPORT_IMAGE: '裸金属创建镜像中',
|
||||||
|
REINSTALLING: '重装中',
|
||||||
|
MODIFY_NETWORK: '裸金属重置网络中',
|
||||||
|
RESTORING: '恢复中',
|
||||||
|
BACKUPING: '创建备份中',
|
||||||
|
MOUNT_FILE_SYSTEM: '挂载文件系统中',
|
||||||
|
UNMOUNT_FILE_SYSTEM: '卸载文件系统中',
|
||||||
|
Rebuilding: '重建中'
|
||||||
}
|
}
|
||||||
return obj[value]
|
return obj[value]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bareMetalColor(value) {
|
export function bareMetalColor(value) {
|
||||||
const obj = {
|
const obj = {
|
||||||
RUNNING: 'success',
|
RUNNING: 'success',
|
||||||
STOPPING: 'warning',
|
STOPPING: 'warning',
|
||||||
|
CREATING: 'warning',
|
||||||
STOPPED: 'danger',
|
STOPPED: 'danger',
|
||||||
STARTING: 'warning',
|
STARTING: 'warning',
|
||||||
REBOOTING: 'warning',
|
REBOOTING: 'warning',
|
||||||
PENDING: 'info',
|
PENDING: 'info',
|
||||||
CREATE_FAILED: 'danger'
|
CREATE_FAILED: 'danger',
|
||||||
|
RESIZING: 'info',
|
||||||
|
VERIFY_RESIZE: 'info',
|
||||||
|
RESTARTING: 'info',
|
||||||
|
WAITING: 'info',
|
||||||
|
DELETING: 'danger',
|
||||||
|
DELETE: 'info',
|
||||||
|
ERROR: 'danger',
|
||||||
|
EXPIRED: 'warning',
|
||||||
|
REBUILD: 'info',
|
||||||
|
CREATING_IMAGE: 'info',
|
||||||
|
SUSPENDED: 'danger',
|
||||||
|
SUSPENDING: 'warning',
|
||||||
|
MIGRATING: 'info',
|
||||||
|
BUILD_BACKUP: 'info',
|
||||||
|
EXPORT_IMAGE: 'info',
|
||||||
|
REINSTALLING: 'info',
|
||||||
|
MODIFY_NETWORK: 'info',
|
||||||
|
RESTORING: 'info',
|
||||||
|
BACKUPING: 'info',
|
||||||
|
MOUNT_FILE_SYSTEM: 'info',
|
||||||
|
UNMOUNT_FILE_SYSTEM: 'info',
|
||||||
|
Rebuilding: 'info'
|
||||||
}
|
}
|
||||||
return obj[value]
|
return obj[value]
|
||||||
}
|
}
|
||||||
|
|
|
@ -942,5 +942,58 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trigger: trigger
|
trigger: trigger
|
||||||
|
},
|
||||||
|
ctstackBMSName: {
|
||||||
|
// 长度6到15位,可以为字母数字和中划线,首字符不能为中划线和数字,不能以中划线结尾
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
const reg = /^[a-zA-Z][a-zA-Z0-9\-]{4,13}[a-zA-Z0-9]$/
|
||||||
|
if (reg.test(value)) {
|
||||||
|
callback()
|
||||||
|
} else {
|
||||||
|
callback(new Error('长度6到15位,可以为字母数字和中划线,首字符不能为中划线和数字,不能以中划线结尾'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: trigger
|
||||||
|
},
|
||||||
|
ctstackBMSPassword: {
|
||||||
|
// 密码校验8~30 个字符,必须包含大小写字母,同时必须包含一个数字或者特殊字符,且不能以斜线号(/)开头,不能包含连续字符
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
const message = new Error('密码校验8~30 个字符,必须包含大小写字母,同时必须包含一个数字或者特殊字符,且不能以斜线号(/)开头,不能包含连续字符')
|
||||||
|
// 检查长度要求
|
||||||
|
if (value.length < 8 || value.length > 30) {
|
||||||
|
callback(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查不能以斜线 / 开头
|
||||||
|
if (value.startsWith('/')) {
|
||||||
|
callback(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否包含大小写字母
|
||||||
|
const hasUpperCase = /[A-Z]/.test(value)
|
||||||
|
const hasLowerCase = /[a-z]/.test(value)
|
||||||
|
if (!(hasUpperCase && hasLowerCase)) {
|
||||||
|
callback(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否包含数字或特殊字符
|
||||||
|
const hasNumberOrSpecialChar = /[\d()~`!@#$%^&*_=|{}\[\]:;'"<>,.?/-]/.test(value)
|
||||||
|
if (!hasNumberOrSpecialChar) {
|
||||||
|
callback(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否含有连续字符
|
||||||
|
for (let i = 0; i < value.length - 1; i++) {
|
||||||
|
if (value.charCodeAt(i) + 1 === value.charCodeAt(i + 1)) {
|
||||||
|
callback(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
},
|
||||||
|
trigger: trigger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,44 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="可用区域:" prop="zoneId" :rules="[required]">
|
<cb-form-item label="可用区域:" prop="zoneId" :rules="[required]">
|
||||||
<el-select v-model="addData.zoneId" @change="getSizeData">
|
<el-select v-model="addData.zoneId" @change="getFlavorList">
|
||||||
<el-option v-for="item in zoneData" :key="item.id" :label="item.name" :value="item.zoneId"></el-option>
|
<el-option v-for="item in zoneData" :key="item.id" :label="item.name" :value="item.zoneId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="20">
|
||||||
<cb-form-item label="实例规格:" prop="flavorId" :rules="[required]">
|
<cb-form-item label="实例规格:" prop="deviceType" :rules="[required]">
|
||||||
<el-select v-model="addData.flavorId">
|
<cb-table :data="flavorList" max-height="400px" :loading="flavorLoading" :rows="99999">
|
||||||
<el-option v-for="item in flavorList" :key="item.id" :label="item.name + '(' + item.cpu + 'C/' + item.memory + 'GB' + ')'" :value="item.id"></el-option>
|
<el-table-column label="名称">
|
||||||
</el-select>
|
<template slot-scope="scope">
|
||||||
|
<el-radio :label="scope.row.deviceType" v-model="addData.deviceType" @input="flavorChange">
|
||||||
|
{{ scope.row.deviceType }}
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="CPU">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.cpuSockets }}路{{ scope.row.cpuAmount }}核{{ scope.row.cpuThreadAmount }}线程 </span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="内存(GB)" prop="memSize"> </el-table-column>
|
||||||
|
<el-table-column label="本地磁盘">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>系统盘:{{ scope.row.systemVolumeAmount ? `${scope.row.systemVolumeAmount} * ${scope.row.systemVolumeSize}GB(${scope.row.systemVolumeType})` : '--' }}</div>
|
||||||
|
<div>数据盘:{{ scope.row.dataVolumeAmount ? `${scope.row.dataVolumeAmount} * ${scope.row.dataVolumeSize}GB(${scope.row.dataVolumeType})` : '--' }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="网卡">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>个数:{{ scope.row.nicAmount }}</div>
|
||||||
|
<div>传输速率:{{ scope.row.nicRate }}(GE)</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<span slot="pagination"></span>
|
||||||
|
</cb-table>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<images :add-data="addData" :vendor-id="vendorId" :region-id="addData.regionId"></images>
|
<images :add-data="addData" :vendor-id="vendorId"></images>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="所属VPC:" prop="vpcUuid" :rules="[required]">
|
<cb-form-item label="所属VPC:" prop="vpcUuid" :rules="[required]">
|
||||||
|
@ -33,14 +58,18 @@
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="所属子网:" prop="subnetId" :rules="[required]">
|
<cb-form-item label="所属子网:" prop="subnetUuid" :rules="[required]">
|
||||||
<el-select v-model="addData.subnetId">
|
<el-select v-model="addData.subnetUuid">
|
||||||
<el-option v-for="item in subnetList" :label="item.name" :value="item.id" :key="item.id"></el-option>
|
<el-option v-for="item in subnetList" :label="item.name" :value="item.value" :key="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <flavor :add-data="addData" :list="flavorList" v-if="flavorList.length" :zone-id="addData.zoneId" vendorType='TIANYI'></flavor> -->
|
<el-col :span="12">
|
||||||
|
<cb-form-item label="物理机名称:" prop="name" :rules="[required, ctstackBMSName]">
|
||||||
|
<el-input v-model="addData.name"></el-input>
|
||||||
|
</cb-form-item>
|
||||||
|
</el-col>
|
||||||
<!-- <el-col :span="24">
|
<!-- <el-col :span="24">
|
||||||
<cb-form-item label="登录方式:">
|
<cb-form-item label="登录方式:">
|
||||||
<el-radio-group v-model="keypair" @change="chooseLoginWay">
|
<el-radio-group v-model="keypair" @change="chooseLoginWay">
|
||||||
|
@ -57,31 +86,41 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" v-else-if="keypair == '密码'">
|
<el-col :span="24" v-else-if="keypair == '密码'">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="登录密码:" prop="password" :rules="[required, tyVmPassword]">
|
<cb-form-item label="登录密码:" prop="password" :rules="[required, ctstackBMSPassword]">
|
||||||
<el-input type="password" v-model="addData.password" @blur="PswBlur" show-password></el-input>
|
<el-input type="password" v-model="addData.password" @blur="PswBlur" show-password></el-input>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="确认密码:" prop="endPassword" :rules="[required, tyVmPassword]">
|
<cb-form-item label="确认密码:" prop="endPassword" :rules="[required, ctstackBMSPassword]">
|
||||||
<el-input type="password" v-model="addData.endPassword" @blur="PswBlur"></el-input>
|
<el-input type="password" v-model="addData.endPassword" @blur="PswBlur"></el-input>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="物理机名称:" prop="name" :rules="[required, noChinese]">
|
<cb-form-item label="数量:" prop="orderCount" :rules="[required]">
|
||||||
<el-input v-model="addData.name"></el-input>
|
<el-input-number v-model="addData.orderCount"></el-input-number>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<cb-form-item label="安全组:" prop="groups" :rules="[required]">
|
<cb-form-item label=" 描述:" prop="remark" :rules="[required]">
|
||||||
<el-select v-model="addData.groups" multiple placeholder="请选择">
|
<el-input v-model="addData.remark"></el-input>
|
||||||
<el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.value"> </el-option>
|
</cb-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<cb-form-item label="本地磁盘:" v-if="systemVolumeLabel || dataVolumeLabel">
|
||||||
|
<div v-if="systemVolumeLabel">
|
||||||
|
{{ systemVolumeLabel }}
|
||||||
|
<el-select v-model="addData.systemVolumeRaidUuid" class="w m-l">
|
||||||
|
<el-option v-for="row in systemRaidList" :label="row.nameZh" :value="row.uuid" :key="row.uuid"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</cb-form-item>
|
</div>
|
||||||
</el-col>
|
<div v-if="dataVolumeLabel">
|
||||||
<el-col :span="12">
|
{{ dataVolumeLabel }}
|
||||||
<cb-form-item label="数量:" prop="count" :rules="[required]">
|
<el-select v-model="addData.dataVolumeRaidUuid" class="w m-l">
|
||||||
<el-input-number v-model="addData.count" style="width: 100%" :min="1"></el-input-number>
|
<el-option v-for="row in dataRaidList" :label="row.nameZh" :value="row.uuid" :key="row.uuid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" v-for="(item, index) in addData.diskDevices" :key="index">
|
<el-col :span="24" v-for="(item, index) in addData.diskDevices" :key="index">
|
||||||
|
@ -110,6 +149,7 @@
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="24">
|
<!-- <el-col :span="24">
|
||||||
|
暂不做数据盘
|
||||||
<cb-form-item>
|
<cb-form-item>
|
||||||
<el-button type="primary" @click="addDiskDevices" v-if="addData.diskDevices.length <= 9">添加数据盘</el-button>
|
<el-button type="primary" @click="addDiskDevices" v-if="addData.diskDevices.length <= 9">添加数据盘</el-button>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
|
@ -131,12 +171,12 @@
|
||||||
import validate from '@/validate'
|
import validate from '@/validate'
|
||||||
import { getRegion, getZone } from 'services/platform/index'
|
import { getRegion, getZone } from 'services/platform/index'
|
||||||
import { getVpc } from 'views/resource/ctstack/services/vpcs'
|
import { getVpc } from 'views/resource/ctstack/services/vpcs'
|
||||||
import { getFlavor } from 'views/resource/ctstack/services/flavors'
|
import { getBMSFlavor } from 'views/resource/ctstack/services/flavors'
|
||||||
|
import { getRaids } from 'views/resource/ctstack/services/volume'
|
||||||
import { getSubnet } from 'views/resource/ctstack/services/subnet'
|
import { getSubnet } from 'views/resource/ctstack/services/subnet'
|
||||||
import { getGroup } from 'views/resource/ctstack/services/group'
|
|
||||||
import { getKey } from 'views/resource/ctstack/services/key'
|
import { getKey } from 'views/resource/ctstack/services/key'
|
||||||
import { typeData, dataTypeData } from 'views/resource/ctstack/page/hardDisk/config'
|
import { typeData, dataTypeData } from 'views/resource/ctstack/page/hardDisk/config'
|
||||||
import images from 'views/platform/components/image.vue'
|
import images from './image.vue'
|
||||||
import { encrypt } from '@cmp/cmp-element'
|
import { encrypt } from '@cmp/cmp-element'
|
||||||
import { addBMS } from 'views/resource/ctstack/services/bms.js'
|
import { addBMS } from 'views/resource/ctstack/services/bms.js'
|
||||||
|
|
||||||
|
@ -147,64 +187,79 @@ export default {
|
||||||
type: Object
|
type: Object
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
pwdRule() {
|
|
||||||
return this.$store.state.app.systemConfig.pwdStrength + ',required'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
vendorId: parseInt(this.$router.currentRoute.query.vendorId),
|
vendorId: parseInt(this.$router.currentRoute.query.vendorId),
|
||||||
required: validate.required,
|
required: validate.required,
|
||||||
noChinese: validate.noChinese,
|
ctstackBMSName: validate.ctstackBMSName,
|
||||||
|
ctstackBMSPassword: validate.ctstackBMSPassword,
|
||||||
addData: {
|
addData: {
|
||||||
regionId: '',
|
vendorId: 1, // 当前平台id
|
||||||
zoneId: '',
|
regionId: '', // 页面选择的地域
|
||||||
flavorId: '',
|
zoneId: '', // 页面选择的可用区
|
||||||
name: '',
|
name: '', // 名称,(长度6到15位,可以为字母数字和中划线,首字符不能为中划线和数字,不能以中划线结尾
|
||||||
password: '',
|
hostname: '', // 页面可以不展示,传参与name相同
|
||||||
endPassword: '',
|
remark: '', // 描述
|
||||||
keypairName: '',
|
deviceType: '', // 规格接口的deviceType
|
||||||
imageId: '',
|
imageUuid: '', // 镜像接口的imageUUID
|
||||||
vpcUuid: '',
|
password: '', // 密码-长度8到30位,必须包含大小写字母和(数字或者特殊字符,并且^不可用且不能包含两位以上连续数字)
|
||||||
subnetId: '',
|
vpcUuid: '', // 云管vpc接口的vpcId
|
||||||
count: 1,
|
extIp: '0', // 不启用弹性IP,默认传0
|
||||||
groups: [],
|
systemVolumeRaidUuid: '', // 磁盘raid下拉框接口中的uuid
|
||||||
networks: [],
|
dataVolumeRaidUuid: '', // 磁盘raid下拉框接口中的uuid
|
||||||
diskDevices: []
|
vpcName: '', // 云管vpc接口的name
|
||||||
},
|
master: true, // 默认为true
|
||||||
tyVmPassword: {
|
subnetUuid: '', // 子网接口的subnetUuid
|
||||||
validator: (rule, value, callback) => {
|
cycleCount: 0, // 订购时长,按需订购传0
|
||||||
const users = ['admin', 'adminstartor', 'root', 'nimda', 'rotratsnimda', 'toor']
|
cycleType: 'ondemand', // 订购周期类型 ,取值范围:[MONTH=按月,YEAR=按年,ondemand=按需订购]
|
||||||
const pattern = '^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,26}$'
|
orderCount: 1 // 订购数量
|
||||||
users.forEach(item => {
|
|
||||||
if (value.indexOf(item) != -1) {
|
|
||||||
callback(new Error('密码不能包含用户名或用户名的逆序'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (!value.match(pattern)) {
|
|
||||||
callback(new Error('只能包含大写字母、小写字母、数字和特殊字符(!@$%^-_=+[{}]:,./?~#*)且至少包含四种字符中的三种,密码不能包含用户名或用户名的逆序,长度介于8-26字符'))
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trigger: null
|
|
||||||
},
|
},
|
||||||
regionData: [],
|
regionData: [],
|
||||||
typeData,
|
typeData,
|
||||||
dataTypeData,
|
dataTypeData,
|
||||||
routerList: [],
|
routerList: [],
|
||||||
flavorList: [],
|
flavorList: [],
|
||||||
|
flavorLoading: false,
|
||||||
loginWays: [{ name: '密码' }, { name: '密钥' }],
|
loginWays: [{ name: '密码' }, { name: '密钥' }],
|
||||||
groupList: [],
|
|
||||||
keypairList: [],
|
keypairList: [],
|
||||||
keypair: '密码',
|
keypair: '密码',
|
||||||
zoneData: [],
|
zoneData: [],
|
||||||
subnetList: [],
|
subnetList: [],
|
||||||
loading: false
|
loading: false,
|
||||||
|
systemVolumeLabel: '',
|
||||||
|
dataVolumeLabel: '',
|
||||||
|
systemRaidList: [],
|
||||||
|
dataRaidList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
flavorChange() {
|
||||||
|
const find = this.flavorList.find(({ deviceType }) => this.addData.deviceType)
|
||||||
|
this.systemVolumeLabel = find?.systemVolumeAmount ? `系统盘:${find.systemVolumeAmount}*${find.systemVolumeSize}GB(${find.systemVolumeType})` : ''
|
||||||
|
this.dataVolumeLabel = find?.dataVolumeAmount ? `数据盘:${find.dataVolumeAmount}*${find.dataVolumeSize}GB(${find.dataVolumeType})` : ''
|
||||||
|
this.addData.systemVolumeRaidUuid = ''
|
||||||
|
this.addData.dataVolumeRaidUuid = ''
|
||||||
|
this.systemRaidList = []
|
||||||
|
this.dataRaidList = []
|
||||||
|
if (this.systemVolumeLabel) this.getRaidList('system')
|
||||||
|
if (this.dataVolumeLabel) this.getRaidList('data')
|
||||||
|
},
|
||||||
|
getRaidList(volumeType) {
|
||||||
|
const { regionId, zoneId, deviceType } = this.addData
|
||||||
|
if (!deviceType) return
|
||||||
|
getRaids({
|
||||||
|
vendorId: this.vendorId,
|
||||||
|
regionId,
|
||||||
|
zoneId,
|
||||||
|
deviceType, // 来自规格的deviceType
|
||||||
|
volumeType // system或data,有磁盘是否是系统盘决定
|
||||||
|
}).then(res => {
|
||||||
|
if (res.success) {
|
||||||
|
if (volumeType === 'system') this.systemRaidList = res.data
|
||||||
|
if (volumeType === 'data') this.dataRaidList = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
this.$router.back(-1)
|
this.$router.back(-1)
|
||||||
},
|
},
|
||||||
|
@ -235,13 +290,12 @@ export default {
|
||||||
regionChange() {
|
regionChange() {
|
||||||
if (this.addData.zoneId) this.addData.zoneId = ''
|
if (this.addData.zoneId) this.addData.zoneId = ''
|
||||||
if (this.addData.vpcUuid) this.addData.vpcUuid = ''
|
if (this.addData.vpcUuid) this.addData.vpcUuid = ''
|
||||||
if (this.addData.imageId) this.addData.imageId = ''
|
if (this.addData.imageUuid) this.addData.imageUuid = ''
|
||||||
if (this.addData.subnetId) this.addData.subnetId = ''
|
if (this.addData.subnetUuid) this.addData.subnetUuid = ''
|
||||||
this.subnetList = []
|
this.subnetList = []
|
||||||
this.addData.groups = []
|
|
||||||
this.getZone()
|
this.getZone()
|
||||||
this.getVpcData()
|
this.getVpcData()
|
||||||
this.getKeypair()
|
// this.getKeypair()
|
||||||
},
|
},
|
||||||
// 删除数据盘
|
// 删除数据盘
|
||||||
diskDevicesRemove(index) {
|
diskDevicesRemove(index) {
|
||||||
|
@ -264,7 +318,7 @@ export default {
|
||||||
},
|
},
|
||||||
// 请求子网
|
// 请求子网
|
||||||
getSubnet() {
|
getSubnet() {
|
||||||
this.addData.subnetId = ''
|
this.addData.subnetUuid = ''
|
||||||
const params = JSON.stringify([
|
const params = JSON.stringify([
|
||||||
{
|
{
|
||||||
param: {
|
param: {
|
||||||
|
@ -298,37 +352,26 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
changeVpc() {
|
changeVpc() {
|
||||||
this.addData.subnetId = ''
|
this.addData.vpcName = this.routerList.find(item => item.vpcId === this.addData.vpcUuid)?.name
|
||||||
this.addData.groups = []
|
this.addData.subnetUuid = ''
|
||||||
this.getSubnet()
|
this.getSubnet()
|
||||||
this.getGroupData()
|
|
||||||
},
|
},
|
||||||
// 请求规格
|
// 请求规格
|
||||||
getSizeData() {
|
getFlavorList() {
|
||||||
const params = {
|
const params = {
|
||||||
simple: true
|
vendorId: this.vendorId,
|
||||||
|
regionId: this.addData.regionId,
|
||||||
|
zoneId: this.addData.zoneId
|
||||||
}
|
}
|
||||||
const searchParam = [
|
this.flavorLoading = true
|
||||||
{ param: { vendorId: this.vendorId, regionId: this.addData.regionId }, sign: 'EQ' },
|
getBMSFlavor(params)
|
||||||
{ param: { zone: this.addData.zoneId }, sign: 'LK' }
|
.then(data => {
|
||||||
]
|
|
||||||
params.params = JSON.stringify(searchParam)
|
|
||||||
getFlavor(params).then(data => {
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
this.flavorList = data.data.rows
|
this.flavorList = data.data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
.finally(() => {
|
||||||
// 获取安全组
|
this.flavorLoading = false
|
||||||
getGroupData() {
|
|
||||||
const vpcId = this.routerList.find(item => item.vpcId === this.addData.vpcUuid)?.id
|
|
||||||
getGroup({
|
|
||||||
simple: true,
|
|
||||||
params: JSON.stringify([{ param: { vendorId: this.vendorId, regionId: this.addData.regionId, tenantId: 0, vpcId }, sign: 'EQ' }])
|
|
||||||
}).then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
this.groupList = data.data.rows
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
chooseLoginWay(item) {
|
chooseLoginWay(item) {
|
||||||
|
@ -366,8 +409,8 @@ export default {
|
||||||
let addData = ''
|
let addData = ''
|
||||||
this.$refs.addData.validate(valid => {
|
this.$refs.addData.validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
this.addData.hostname = this.addData.name
|
||||||
this.addData.vendorId = this.vendorId
|
this.addData.vendorId = this.vendorId
|
||||||
this.addData.networks = []
|
|
||||||
if (this.addData.password != this.addData.endPassword && this.keypair == '密码') {
|
if (this.addData.password != this.addData.endPassword && this.keypair == '密码') {
|
||||||
this.$notify({
|
this.$notify({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
@ -375,9 +418,6 @@ export default {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.addData.content) {
|
|
||||||
this.addData.name = this.addData.content + this.addData.name
|
|
||||||
}
|
|
||||||
addData = JSON.parse(JSON.stringify(this.addData))
|
addData = JSON.parse(JSON.stringify(this.addData))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
<template>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="镜像" prop="imageUuid" :rules="[required]">
|
||||||
|
<el-radio-group v-model="type" @change="chooseWay" class="m-r">
|
||||||
|
<el-radio disabled :label="item.value" :key="index" v-for="(item, index) in typeList" border> {{ item.name }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-select filterable v-model="addData.imageUuid" class="w-lg">
|
||||||
|
<el-option v-for="item in imageList" :key="item.imageUUID" :label="`${item.nameZh} ${item.version} ${item.os[0].bits}位`" :value="item.imageUUID"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getBMSImage } from 'views/resource/ctstack/services/image'
|
||||||
|
import validate from '@/validate'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
addData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vendorId: {
|
||||||
|
type: [Number, String]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
required: validate.required,
|
||||||
|
type: 'PUBLIC',
|
||||||
|
typeList: [{ name: '公共镜像', value: 'PUBLIC' }],
|
||||||
|
imageList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'addData.deviceType': {
|
||||||
|
handler(newVal) {
|
||||||
|
this.chooseWay()
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
chooseWay() {
|
||||||
|
this.addData.imageUuid = ''
|
||||||
|
this.getImageData()
|
||||||
|
},
|
||||||
|
getImageData() {
|
||||||
|
if (!this.addData.deviceType) return
|
||||||
|
getBMSImage({
|
||||||
|
vendorId: this.vendorId,
|
||||||
|
regionId: this.addData.regionId,
|
||||||
|
zoneId: this.addData.zoneId,
|
||||||
|
deviceType: this.addData.deviceType //来自规格的deviceType
|
||||||
|
}).then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
this.imageList = data.data
|
||||||
|
if (data.data.length) this.addData.imageUuid = data.data[0].imageUUID
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,16 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<cb-advance-table title="" :data="data" :params="params" :columns="columns" :get-list="getList" :total="total" @select="handleSelectItem" @select-all="handleSelectAll" :loading="loading" :search-configs="searchConfigs">
|
<cb-advance-table title="" :data="data" :params="params" :columns="columns" :get-list="getList" :total="total" :loading="loading" :search-configs="searchConfigs">
|
||||||
<template v-slot:action>
|
<template v-slot:action>
|
||||||
<el-button type="primary" @click="handleAdd()"> 新增 </el-button>
|
<el-button type="primary" @click="handleAdd()"> 新增 </el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #instanceId="val, record">
|
<template #instanceUuid="val, record">
|
||||||
<span class="detail-href" @click="getDiskList(record)">{{ val }}</span>
|
<span class="detail-href" @click="getDiskList(record)">{{ val }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #state="val">
|
<template #ebmState="val">
|
||||||
<cb-status-icon :type="val | bareMetalColor">{{ val | bareMetalState }}</cb-status-icon>
|
<cb-status-icon :type="val | bareMetalColor">{{ val | bareMetalState }}</cb-status-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #operate="val, record">
|
<template #operate="val, record">
|
||||||
|
<el-button type="text" @click="handleEdit(record)"> 编辑 </el-button>
|
||||||
|
<el-button type="text" @click="handleDelete(record)"> 删除 </el-button>
|
||||||
|
<!-- <div class="action-divider"></div>
|
||||||
<el-button type="text" @click="reboot(record)"> 重启 </el-button>
|
<el-button type="text" @click="reboot(record)"> 重启 </el-button>
|
||||||
<div class="action-divider"></div>
|
<div class="action-divider"></div>
|
||||||
<el-button type="text" @click="bootup(record)"> 开机 </el-button>
|
<el-button type="text" @click="bootup(record)"> 开机 </el-button>
|
||||||
|
@ -20,27 +23,12 @@
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<span class="el-dropdown-link"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
|
<span class="el-dropdown-link"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item @click.native="edt(record)" :disabled="record.status == 'PENDING'"> 退还 </el-dropdown-item>
|
<el-dropdown-item @click.native="edt(record)" :disabled="record.ebmState == 'CREATING'"> 退还 </el-dropdown-item>
|
||||||
<el-dropdown-item @click.native="reload(record)"> 重装 </el-dropdown-item>
|
<el-dropdown-item @click.native="reload(record)"> 重装 </el-dropdown-item>
|
||||||
<el-dropdown-item @click.native="edit(record)"> 改名 </el-dropdown-item>
|
|
||||||
<el-dropdown-item @click.native="edit(record)" disabled> 分配 </el-dropdown-item>
|
|
||||||
<el-dropdown-item @click.native="edit(record)" disabled> 回收 </el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown> -->
|
||||||
</template>
|
</template>
|
||||||
</cb-advance-table>
|
</cb-advance-table>
|
||||||
<!-- 更改名称 -->
|
|
||||||
<el-dialog width="30%" title="更改名称" :close-on-click-modal="false" v-if="editData.dialog" :visible.sync="editData.dialog">
|
|
||||||
<cb-form :model="editData.data" ref="editData" label-width="50px">
|
|
||||||
<cb-form-item label="名称" prop="newName">
|
|
||||||
<el-input v-model="editData.data.newName"></el-input>
|
|
||||||
</cb-form-item>
|
|
||||||
</cb-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="ghost" @click.native="editData.dialog = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click.native="editSubmit">确定</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
<!-- 硬盘列表 -->
|
<!-- 硬盘列表 -->
|
||||||
<el-dialog width="50%" title="硬盘列表" :close-on-click-modal="false" v-if="diskSign" :visible.sync="diskSign">
|
<el-dialog width="50%" title="硬盘列表" :close-on-click-modal="false" v-if="diskSign" :visible.sync="diskSign">
|
||||||
<cb-smart-table ref="list" :data="diskData" :rows="5" style="margin-top: 10px">
|
<cb-smart-table ref="list" :data="diskData" :rows="5" style="margin-top: 10px">
|
||||||
|
@ -59,20 +47,14 @@
|
||||||
<el-dialog width="45%" title="重装" :close-on-click-modal="false" v-if="Reloading" :visible.sync="Reloading" :append-to-body="true">
|
<el-dialog width="45%" title="重装" :close-on-click-modal="false" v-if="Reloading" :visible.sync="Reloading" :append-to-body="true">
|
||||||
<cb-form :model="reloadData.data" ref="reloadData" label-width="140px">
|
<cb-form :model="reloadData.data" ref="reloadData" label-width="140px">
|
||||||
<h3>当前配置</h3>
|
<h3>当前配置</h3>
|
||||||
<cb-form-item label="镜像名称">{{ reloadData.row.operatingSystemType }}</cb-form-item>
|
<cb-form-item label="镜像名称">{{ reloadData.row.osTypeName }}</cb-form-item>
|
||||||
<cb-form-item label="RAID类型">{{ reloadData.row.raidType }}</cb-form-item>
|
|
||||||
<h3>重装为</h3>
|
<h3>重装为</h3>
|
||||||
<cb-form-item label="镜像类型">{{ reloadData.row.operatingSystemType }}</cb-form-item>
|
<cb-form-item label="镜像类型">{{ reloadData.row.osTypeName }}</cb-form-item>
|
||||||
<cb-form-item label="镜像">
|
<cb-form-item label="镜像">
|
||||||
<el-select v-model="reloadData.data.operatingSystem" placeholder="请选择镜像">
|
<el-select v-model="reloadData.data.operatingSystem" placeholder="请选择镜像">
|
||||||
<el-option v-for="item in selectCombo.operatingSystem.linux" :key="item" :label="item" :value="item"> </el-option>
|
<el-option v-for="item in selectCombo.operatingSystem.linux" :key="item" :label="item" :value="item"> </el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</cb-form-item>
|
</cb-form-item>
|
||||||
<cb-form-item label="RAID类型" prop="raidType">
|
|
||||||
<el-select v-model="reloadData.data.raidType" placeholder="请选择类型">
|
|
||||||
<el-option v-for="item in selectCombo.raidType" :key="item" :label="item" :value="item"> </el-option>
|
|
||||||
</el-select>
|
|
||||||
</cb-form-item>
|
|
||||||
<cb-form-item label="主机安全agent">
|
<cb-form-item label="主机安全agent">
|
||||||
<el-radio v-model="reloadData.data.enhancedService.SecurityService.Enabled" label="true">开启</el-radio>
|
<el-radio v-model="reloadData.data.enhancedService.SecurityService.Enabled" label="true">开启</el-radio>
|
||||||
<el-radio v-model="reloadData.data.enhancedService.SecurityService.Enabled" label="false">关闭</el-radio>
|
<el-radio v-model="reloadData.data.enhancedService.SecurityService.Enabled" label="false">关闭</el-radio>
|
||||||
|
@ -90,75 +72,69 @@
|
||||||
<el-button type="primary" :loading="subLoading" @click.native="ok">确定</el-button>
|
<el-button type="primary" :loading="subLoading" @click.native="ok">确定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<modifyName :add-data="modifyDialog" @back="getList" v-if="modifyDialog.dialog"></modifyName>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { bareMetalState, bareMetalColor } from 'filters'
|
import { bareMetalState, bareMetalColor } from 'filters'
|
||||||
import { getBareMetalList, modifyBareMetal, bmsReboot, bmsBootUp, bmsStop, bmsedt, getDisk, getCombo, bmsReload } from 'views/resource/ctstack/services/bms.js'
|
import { getBareMetalList, modifyBareMetal, bmsReboot, bmsBootUp, bmsStop, bmsedt, getDisk, getCombo, bmsReload, bmsDelete } from 'views/resource/ctstack/services/bms.js'
|
||||||
import { removeVmUsers } from 'views/resource/ctstack/services/vm.js'
|
|
||||||
import { getRegion } from 'services/platform/index'
|
import { getRegion } from 'services/platform/index'
|
||||||
|
import modifyName from './modifyName.vue'
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
|
||||||
type: 'selection'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'ID',
|
label: 'ID',
|
||||||
prop: 'instanceId',
|
prop: 'instanceUuid',
|
||||||
disabled: true,
|
disabled: true,
|
||||||
scopedSlots: { customRender: 'instanceId' }
|
scopedSlots: { customRender: 'instanceUuid' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '名称',
|
label: '名称',
|
||||||
prop: 'instanceName',
|
prop: 'name',
|
||||||
disabled: true
|
disabled: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '状态',
|
label: '状态',
|
||||||
prop: 'status',
|
prop: 'ebmState',
|
||||||
scopedSlots: { customRender: 'state' }
|
scopedSlots: { customRender: 'ebmState' }
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '机型',
|
|
||||||
prop: 'flavorName'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '可用区',
|
label: '可用区',
|
||||||
prop: 'zone'
|
prop: 'zoneName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '私有网络',
|
label: '私有网络',
|
||||||
prop: 'vpcId'
|
prop: 'vpcName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '子网',
|
label: '子网',
|
||||||
prop: 'subnetId'
|
prop: 'subnetName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '公网IP',
|
label: '公网IP',
|
||||||
prop: ''
|
prop: 'publicIP'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '内网IP',
|
label: '内网IP',
|
||||||
prop: ''
|
prop: 'privateIP'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '操作系统',
|
label: '操作系统',
|
||||||
prop: 'operatingSystemType'
|
prop: 'osTypeName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'RAID类型',
|
label: '描述',
|
||||||
prop: 'raidType'
|
prop: 'remark'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '操作',
|
label: '操作',
|
||||||
disabled: true,
|
disabled: true,
|
||||||
width: '220px',
|
width: '160px',
|
||||||
scopedSlots: { customRender: 'operate' }
|
scopedSlots: { customRender: 'operate' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: { modifyName },
|
||||||
props: {
|
props: {
|
||||||
platformObject: {
|
platformObject: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -201,11 +177,6 @@ export default {
|
||||||
{ type: 'Select', label: '所属地域', data: [], value: 'regionId', props: { value: 'regionId' } },
|
{ type: 'Select', label: '所属地域', data: [], value: 'regionId', props: { value: 'regionId' } },
|
||||||
{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }
|
{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }
|
||||||
],
|
],
|
||||||
// 编辑数据
|
|
||||||
editData: {
|
|
||||||
dialog: false,
|
|
||||||
data: {}
|
|
||||||
},
|
|
||||||
diskSign: false,
|
diskSign: false,
|
||||||
diskData: [],
|
diskData: [],
|
||||||
// 重装
|
// 重装
|
||||||
|
@ -213,9 +184,8 @@ export default {
|
||||||
ruleForm: {},
|
ruleForm: {},
|
||||||
reloadData: {
|
reloadData: {
|
||||||
data: {
|
data: {
|
||||||
instanceId: '',
|
instanceUuid: '',
|
||||||
raidType: '',
|
osTypeName: '',
|
||||||
operatingSystemType: '',
|
|
||||||
operatingSystem: '',
|
operatingSystem: '',
|
||||||
loginSettings: {
|
loginSettings: {
|
||||||
Password: '',
|
Password: '',
|
||||||
|
@ -230,10 +200,46 @@ export default {
|
||||||
row: {}
|
row: {}
|
||||||
},
|
},
|
||||||
comboData: '',
|
comboData: '',
|
||||||
selectCombo: {}
|
selectCombo: {},
|
||||||
|
modifyDialog: {
|
||||||
|
dialog: false,
|
||||||
|
data: {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 修改名称
|
||||||
|
handleEdit(row) {
|
||||||
|
const { id, name, regionId, zoneId, remark = '' } = row
|
||||||
|
this.modifyDialog = {
|
||||||
|
dialog: true,
|
||||||
|
data: {
|
||||||
|
id,
|
||||||
|
displayName: name,
|
||||||
|
regionId,
|
||||||
|
zoneId,
|
||||||
|
remark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm('此操作将删除该实例, 是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
bmsDelete({ id: row.id }).then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
this.$message({
|
||||||
|
type: 'success',
|
||||||
|
message: data.message
|
||||||
|
})
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
// 重装
|
// 重装
|
||||||
ok() {
|
ok() {
|
||||||
this.$refs.reloadData.validate(valid => {
|
this.$refs.reloadData.validate(valid => {
|
||||||
|
@ -257,16 +263,15 @@ export default {
|
||||||
},
|
},
|
||||||
reload(row) {
|
reload(row) {
|
||||||
const params = {
|
const params = {
|
||||||
zone: ['yfm14az1']
|
zoneName: ['yfm14az1']
|
||||||
}
|
}
|
||||||
getCombo(this.platformObject.vendorId, params).then(res => {
|
getCombo(this.platformObject.vendorId, params).then(res => {
|
||||||
this.comboData = res.data.flavorSet
|
this.comboData = res.data.flavorSet
|
||||||
this.Reloading = true
|
this.Reloading = true
|
||||||
this.reloadData.row = row
|
this.reloadData.row = row
|
||||||
this.reloadData.data = {
|
this.reloadData.data = {
|
||||||
instanceId: row.instanceId,
|
instanceUuid: row.instanceUuid,
|
||||||
raidType: row.raidType,
|
osTypeName: row.osTypeName,
|
||||||
operatingSystemType: row.operatingSystemType,
|
|
||||||
operatingSystem: row.operatingSystem,
|
operatingSystem: row.operatingSystem,
|
||||||
loginSettings: {
|
loginSettings: {
|
||||||
Password: ''
|
Password: ''
|
||||||
|
@ -288,7 +293,7 @@ export default {
|
||||||
getArea() {
|
getArea() {
|
||||||
// 获取套餐
|
// 获取套餐
|
||||||
const params = {
|
const params = {
|
||||||
zone: ['yfm14az1']
|
zoneName: ['yfm14az1']
|
||||||
}
|
}
|
||||||
getCombo(this.platformObject.vendorId, params).then(res => {
|
getCombo(this.platformObject.vendorId, params).then(res => {
|
||||||
this.comboData = res.data.flavorSet
|
this.comboData = res.data.flavorSet
|
||||||
|
@ -312,7 +317,7 @@ export default {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$cmpDelete(close => {
|
this.$cmpDelete(close => {
|
||||||
bmsedt([row.instanceId]).then(data => {
|
bmsedt([row.instanceUuid]).then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
this.$message({
|
this.$message({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
@ -375,66 +380,8 @@ export default {
|
||||||
}, 45000)
|
}, 45000)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
edit(row) {
|
|
||||||
this.editData = {
|
|
||||||
dialog: true,
|
|
||||||
data: {
|
|
||||||
id: row.id,
|
|
||||||
instanceId: row.instanceId,
|
|
||||||
newName: row.instanceName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
editSubmit() {
|
|
||||||
this.$refs.editData.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
modifyBareMetal(this.editData.data).then(res => {
|
|
||||||
if (res.success) {
|
|
||||||
this.$message.success(res.message)
|
|
||||||
this.editData.dialog = false
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 全选
|
|
||||||
handleSelectAll(selection) {
|
|
||||||
this.refreshId()
|
|
||||||
if (selection.length) {
|
|
||||||
// 全选情况下
|
|
||||||
selection.forEach(item => {
|
|
||||||
if (this.idList.indexOf(item.id) == -1) {
|
|
||||||
this.selectList.push(item)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 全不选情况下
|
|
||||||
this.list.forEach(item => {
|
|
||||||
if (this.idList.indexOf(item.id) > -1) {
|
|
||||||
for (let j = 0; j < this.selectList.length; j++) {
|
|
||||||
const row = this.selectList[j]
|
|
||||||
if (item.id == row.id) {
|
|
||||||
this.selectList.splice(j, 1)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
// const params = {
|
|
||||||
// page: this.params.page,
|
|
||||||
// rows: this.params.rows,
|
|
||||||
// params: JSON.stringify([{
|
|
||||||
// param: {
|
|
||||||
// vendorId: this.platformObject.vendorId,
|
|
||||||
// },
|
|
||||||
// sign: 'EQ'
|
|
||||||
// }])
|
|
||||||
// }
|
|
||||||
getBareMetalList(this.params)
|
getBareMetalList(this.params)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog title="编辑" width="40%" :close-on-click-modal="false" v-if="addData.dialog" :visible.sync="addData.dialog">
|
||||||
|
<cb-form :model="addData.data" ref="data">
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="24">
|
||||||
|
<cb-form-item label="名称:" prop="displayName" :rules="[required]" required-message="请输入名称">
|
||||||
|
<el-input v-model="addData.data.displayName"></el-input>
|
||||||
|
</cb-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<cb-form-item label="备注:" prop="remark" :rules="[required]" required-message="请输入备注">
|
||||||
|
<el-input v-model="addData.data.remark"></el-input>
|
||||||
|
</cb-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</cb-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="ghost" @click.native="addData.dialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click.native="ok" :loading="loading">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { modifyBareMetal } from 'views/resource/ctstack/services/bms'
|
||||||
|
import validate from '@/validate'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
addData: {
|
||||||
|
type: Object,
|
||||||
|
default: function () {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
labelIds: []
|
||||||
|
},
|
||||||
|
dialog: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { required: validate.required, loading: false }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ok() {
|
||||||
|
this.$refs.data.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.loading = true
|
||||||
|
modifyBareMetal(this.addData.data)
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
this.$message.success(data.message)
|
||||||
|
this.$emit('back')
|
||||||
|
this.addData.dialog = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,61 +1,59 @@
|
||||||
import { request } from '@cmp/cmp-element'
|
import { request } from '@cmp/cmp-element'
|
||||||
import { wrapperParams } from 'utils'
|
import { wrapperParams } from 'utils'
|
||||||
|
const baseUrl = '/cmp/plugins/ctstack/v1/physical/servers'
|
||||||
export function getBareMetalList(params) {
|
export function getBareMetalList(params) {
|
||||||
return request.get('/cmp/plugins/ctstack/v1/bms', {
|
return request.get(baseUrl, {
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新建 获取套餐列表
|
// 修改BMS名称
|
||||||
export function getCombo(id, params) {
|
export function modifyBareMetal(params) {
|
||||||
return request.post(`/cmp/plugins/ctstack/v1/bms/describeFlavors/${id}`, wrapperParams(params))
|
return request.put(`${baseUrl}/${params.id}`, wrapperParams(params))
|
||||||
}
|
}
|
||||||
// 获取运营商
|
|
||||||
export function getOperator(params) {
|
export function bmsDelete(params) {
|
||||||
return request.post('/cmp/plugins/ctstack/v1/bms/describeEIPIspInfo', wrapperParams(params))
|
return request.delete(`${baseUrl}/${params.id}`)
|
||||||
}
|
|
||||||
// 获取子网
|
|
||||||
export function getBareSubnet(id, params) {
|
|
||||||
return request.post(`/cmp/plugins/ctstack/v1/bms/describeSubnets/${id}`, wrapperParams(params))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新建BMS
|
// 新建BMS
|
||||||
export function addBMS(id, params) {
|
export function addBMS(params) {
|
||||||
return request.post(`/cmp/plugins/ctstack/v1/bms/runInstances/${id}`, wrapperParams(params))
|
return request.post(baseUrl, wrapperParams(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改BMS名称
|
// 假的
|
||||||
export function modifyBareMetal(params) {
|
export function getCombo(params) {
|
||||||
return request.post(`/cmp/plugins/ctstack/v1/bms/modifyAttribute/${params.id}`, wrapperParams(params))
|
return request.get(baseUrl, {
|
||||||
|
params
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重启
|
// 重启
|
||||||
export function bmsReboot(params) {
|
export function bmsReboot(params) {
|
||||||
return request.patch(`/cmp/plugins/ctstack/v1/bms/reboot/${params.id}`)
|
return request.patch(`${baseUrl}/reboot/${params.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开机
|
// 开机
|
||||||
export function bmsBootUp(params) {
|
export function bmsBootUp(params) {
|
||||||
return request.patch(`/cmp/plugins/ctstack/v1/bms/start/${params.id}`)
|
return request.patch(`${baseUrl}/start/${params.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关机
|
// 关机
|
||||||
export function bmsStop(params) {
|
export function bmsStop(params) {
|
||||||
return request.patch(`/cmp/plugins/ctstack/v1/bms/stop/${params.id}`)
|
return request.patch(`${baseUrl}/stop/${params.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退还实例
|
// 退还实例
|
||||||
export function bmsedt(params) {
|
export function bmsedt(params) {
|
||||||
return request.post('/cmp/plugins/ctstack/v1/bms/terminateInstances', wrapperParams(params))
|
return request.post('${baseUrl}/terminateInstances', wrapperParams(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取硬盘列表
|
// 获取硬盘列表
|
||||||
export function getDisk(params) {
|
export function getDisk(params) {
|
||||||
return request.get(`/cmp/plugins/ctstack/v1/bms/disks/${params.id}`)
|
return request.get(`${baseUrl}/disks/${params.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重装
|
// 重装
|
||||||
export function bmsReload(id, params) {
|
export function bmsReload(id, params) {
|
||||||
return request.post(`/cmp/plugins/ctstack/v1/bms/resetInstance/${id}`, wrapperParams(params))
|
return request.post(`${baseUrl}/resetInstance/${id}`, wrapperParams(params))
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,3 +45,9 @@ export function unbindFlavor(params) {
|
||||||
export function getFlavorListZone(id) {
|
export function getFlavorListZone(id) {
|
||||||
return request.get(`${url}/listZone/${id}`)
|
return request.get(`${url}/listZone/${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getBMSFlavor(params) {
|
||||||
|
return request.get(`${url}/listPhysical`, {
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -84,3 +84,8 @@ export function patchImage(action, params) {
|
||||||
export function volumeImage(id) {
|
export function volumeImage(id) {
|
||||||
return request.get(`${imageUrl}/${id}/volumes`)
|
return request.get(`${imageUrl}/${id}/volumes`)
|
||||||
}
|
}
|
||||||
|
export function getBMSImage(params) {
|
||||||
|
return request.get(`${imageUrl}/listPhysical`, {
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -45,3 +45,9 @@ export function getVolumeVms(params) {
|
||||||
params: wrapperParams(params)
|
params: wrapperParams(params)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRaids(params) {
|
||||||
|
return request.get(`${volumeUrl}/raids`, {
|
||||||
|
params: wrapperParams(params)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue