469 lines
15 KiB
Vue
469 lines
15 KiB
Vue
<template>
|
||
<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">
|
||
<template v-slot:action>
|
||
<el-button type="primary" @click="handleAdd()"> 新增 </el-button>
|
||
</template>
|
||
<template #instanceId="val, record">
|
||
<span class="detail-href" @click="getDiskList(record)">{{ val }}</span>
|
||
</template>
|
||
<template #state="val">
|
||
<cb-status-icon :type="val | bareMetalColor">{{ val | bareMetalState }}</cb-status-icon>
|
||
</template>
|
||
<template #operate="val, record">
|
||
<el-button type="text" @click="reboot(record)"> 重启 </el-button>
|
||
<div class="action-divider"></div>
|
||
<el-button type="text" @click="bootup(record)"> 开机 </el-button>
|
||
<div class="action-divider"></div>
|
||
<el-button type="text" @click="stop(record)"> 关机 </el-button>
|
||
<div class="action-divider"></div>
|
||
<el-dropdown trigger="click">
|
||
<span class="el-dropdown-link"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
|
||
<el-dropdown-menu slot="dropdown">
|
||
<el-dropdown-item @click.native="edt(record)" :disabled="record.status == 'PENDING'"> 退还 </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>
|
||
</template>
|
||
</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">
|
||
<cb-smart-table ref="list" :data="diskData" :rows="5" style="margin-top: 10px">
|
||
<el-table-column show-overflow-tooltip label="硬盘ID" prop="diskId"></el-table-column>
|
||
<el-table-column show-overflow-tooltip label="硬盘名称" prop="diskName"></el-table-column>
|
||
<el-table-column show-overflow-tooltip label="硬盘大小" prop="diskSize"></el-table-column>
|
||
<el-table-column show-overflow-tooltip label="硬盘类型" prop="diskType"></el-table-column>
|
||
<el-table-column show-overflow-tooltip label="创建时间" prop="createdTime"></el-table-column>
|
||
</cb-smart-table>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="ghost" @click.native="diskSign = false">取消</el-button>
|
||
<el-button type="primary" @click.native="diskSign = false">确定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- 重装 -->
|
||
<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">
|
||
<h3>当前配置</h3>
|
||
<cb-form-item label="镜像名称">{{ reloadData.row.operatingSystemType }}</cb-form-item>
|
||
<cb-form-item label="RAID类型">{{ reloadData.row.raidType }}</cb-form-item>
|
||
<h3>重装为</h3>
|
||
<cb-form-item label="镜像类型">{{ reloadData.row.operatingSystemType }}</cb-form-item>
|
||
<cb-form-item label="镜像">
|
||
<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-select>
|
||
</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">
|
||
<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>
|
||
</cb-form-item>
|
||
<cb-form-item label="新密码" prop="loginSettings.Password" validate="required,tceClusterPassword" required-message="请输入密码">
|
||
<el-input v-model="reloadData.data.loginSettings.Password" show-password></el-input>
|
||
<span style="display: block; font-size: 8px">请输入8~16位密码,密码需要包含字母,数字和特殊符号三种中的三种</span>
|
||
</cb-form-item>
|
||
<cb-form-item label="确认密码" prop="loginSettings.Password_config" validate="required,tceClusterPassword" required-message="请输入确认密码">
|
||
<el-input v-model="reloadData.data.loginSettings.Password_config" show-password></el-input>
|
||
</cb-form-item>
|
||
</cb-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="ghost" @click.native="Reloading = false">取消</el-button>
|
||
<el-button type="primary" :loading="subLoading" @click.native="ok">确定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { bareMetalState, bareMetalColor } from 'filters'
|
||
import { getBareMetalList, modifyBareMetal, bmsReboot, bmsBootUp, bmsStop, bmsedt, getDisk, getCombo, bmsReload } from 'views/resource/ctstack/services/bms.js'
|
||
import { removeVmUsers } from 'views/resource/ctstack/services/vm.js'
|
||
import { getRegion } from 'services/platform/index'
|
||
const columns = [
|
||
{
|
||
type: 'selection'
|
||
},
|
||
{
|
||
label: 'ID',
|
||
prop: 'instanceId',
|
||
disabled: true,
|
||
scopedSlots: { customRender: 'instanceId' }
|
||
},
|
||
{
|
||
label: '名称',
|
||
prop: 'instanceName',
|
||
disabled: true
|
||
},
|
||
{
|
||
label: '状态',
|
||
prop: 'status',
|
||
scopedSlots: { customRender: 'state' }
|
||
},
|
||
{
|
||
label: '机型',
|
||
prop: 'flavorName'
|
||
},
|
||
{
|
||
label: '可用区',
|
||
prop: 'zone'
|
||
},
|
||
{
|
||
label: '私有网络',
|
||
prop: 'vpcId'
|
||
},
|
||
{
|
||
label: '子网',
|
||
prop: 'subnetId'
|
||
},
|
||
{
|
||
label: '公网IP',
|
||
prop: ''
|
||
},
|
||
{
|
||
label: '内网IP',
|
||
prop: ''
|
||
},
|
||
{
|
||
label: '操作系统',
|
||
prop: 'operatingSystemType'
|
||
},
|
||
{
|
||
label: 'RAID类型',
|
||
prop: 'raidType'
|
||
},
|
||
{
|
||
label: '操作',
|
||
disabled: true,
|
||
width: '220px',
|
||
scopedSlots: { customRender: 'operate' }
|
||
}
|
||
]
|
||
export default {
|
||
components: {},
|
||
props: {
|
||
platformObject: {
|
||
type: Object,
|
||
default: function () {
|
||
return {
|
||
huaweiId: -1,
|
||
operate: -1
|
||
}
|
||
}
|
||
}
|
||
},
|
||
mounted() {
|
||
this.getRegion()
|
||
},
|
||
watch: {
|
||
platformObject: {
|
||
handler(newVal, oldVal) {
|
||
this.searchConfigs = [
|
||
{ type: 'Input', label: '名称', value: 'name' },
|
||
{ type: 'Select', label: '所属地域', data: [], value: 'regionId', props: { value: 'regionId' } },
|
||
{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }
|
||
]
|
||
},
|
||
deep: true
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
columns,
|
||
loading: false,
|
||
subLoading: false,
|
||
params: {
|
||
page: 1,
|
||
rows: 10
|
||
},
|
||
data: [],
|
||
total: 0,
|
||
searchConfigs: [
|
||
{ type: 'Input', label: '名称', value: 'name' },
|
||
{ type: 'Select', label: '所属地域', data: [], value: 'regionId', props: { value: 'regionId' } },
|
||
{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }
|
||
],
|
||
// 编辑数据
|
||
editData: {
|
||
dialog: false,
|
||
data: {}
|
||
},
|
||
diskSign: false,
|
||
diskData: [],
|
||
// 重装
|
||
Reloading: false,
|
||
ruleForm: {},
|
||
reloadData: {
|
||
data: {
|
||
instanceId: '',
|
||
raidType: '',
|
||
operatingSystemType: '',
|
||
operatingSystem: '',
|
||
loginSettings: {
|
||
Password: '',
|
||
Password_config: ''
|
||
},
|
||
enhancedService: {
|
||
SecurityService: {
|
||
Enabled: ''
|
||
}
|
||
}
|
||
},
|
||
row: {}
|
||
},
|
||
comboData: '',
|
||
selectCombo: {}
|
||
}
|
||
},
|
||
methods: {
|
||
// 重装
|
||
ok() {
|
||
this.$refs.reloadData.validate(valid => {
|
||
if (valid) {
|
||
this.subLoading = true
|
||
if (this.reloadData.data.loginSettings.Password !== this.reloadData.data.loginSettings.Password_config) {
|
||
this.$message.error('两次密码输入不一致')
|
||
this.subLoading = false
|
||
} else {
|
||
this.reloadData.data.loginSettings.Password = window.btoa(this.reloadData.data.loginSettings.Password)
|
||
bmsReload(this.platformObject.vendorId, this.reloadData.data).then(res => {
|
||
this.subLoading = false
|
||
if (res.success) {
|
||
this.$message.success(res.message)
|
||
this.Reloading = false
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
reload(row) {
|
||
const params = {
|
||
zone: ['yfm14az1']
|
||
}
|
||
getCombo(this.platformObject.vendorId, params).then(res => {
|
||
this.comboData = res.data.flavorSet
|
||
this.Reloading = true
|
||
this.reloadData.row = row
|
||
this.reloadData.data = {
|
||
instanceId: row.instanceId,
|
||
raidType: row.raidType,
|
||
operatingSystemType: row.operatingSystemType,
|
||
operatingSystem: row.operatingSystem,
|
||
loginSettings: {
|
||
Password: ''
|
||
},
|
||
enhancedService: {
|
||
SecurityService: {
|
||
Enabled: 'false'
|
||
}
|
||
}
|
||
}
|
||
this.comboData.forEach(item => {
|
||
if (item.flavorId == row.flavorId) {
|
||
this.selectCombo = item
|
||
}
|
||
})
|
||
})
|
||
},
|
||
// 获取套参
|
||
getArea() {
|
||
// 获取套餐
|
||
const params = {
|
||
zone: ['yfm14az1']
|
||
}
|
||
getCombo(this.platformObject.vendorId, params).then(res => {
|
||
this.comboData = res.data.flavorSet
|
||
})
|
||
},
|
||
// 获取硬盘列表
|
||
getDiskList(row) {
|
||
this.diskSign = true
|
||
getDisk({ id: row.id }).then(res => {
|
||
this.diskData = res.data
|
||
})
|
||
},
|
||
handleAdd() {
|
||
this.$router.push({ name: 'ctstackAddBareMetal', query: { vendorId: this.platformObject.vendorId } })
|
||
},
|
||
// 退还实例
|
||
edt(row) {
|
||
this.$confirm('此操作将退还实例,退回后,磁盘将被格式化且不可恢复,请提前备份数据。物理服务器关联的网络资源将自动解除。是否继续?', '提示', {
|
||
confirmButtonText: '退还',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
this.$cmpDelete(close => {
|
||
bmsedt([row.instanceId]).then(data => {
|
||
if (data.success) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: data.message
|
||
})
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 5000)
|
||
close()
|
||
}
|
||
})
|
||
})
|
||
})
|
||
},
|
||
reboot(row) {
|
||
bmsReboot({ id: row.id }).then(data => {
|
||
if (data.success) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: data.message
|
||
})
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 2000)
|
||
}
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 70000)
|
||
})
|
||
},
|
||
bootup(row) {
|
||
bmsBootUp({ id: row.id }).then(data => {
|
||
if (data.success) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: data.message
|
||
})
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 2000)
|
||
}
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 25000)
|
||
})
|
||
},
|
||
stop(row) {
|
||
bmsStop({ id: row.id }).then(data => {
|
||
if (data.success) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: data.message
|
||
})
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 2000)
|
||
}
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 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() {
|
||
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)
|
||
.then(res => {
|
||
if (res.success) {
|
||
this.data = res.data.rows
|
||
this.total = res.data.total
|
||
}
|
||
})
|
||
.finally(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 获取域
|
||
getRegion() {
|
||
getRegion({ vendorId: this.platformObject.vendorId }).then(data => {
|
||
if (data.success) {
|
||
this.regionList = data.data
|
||
this.searchConfigs[1].data = data.data
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.el-select {
|
||
width: 300px;
|
||
}
|
||
.el-input {
|
||
width: 300px;
|
||
}
|
||
</style>
|