cmc-web/webs/cmp-web/src/views/resource/ctstack/page/secretKey.vue

469 lines
14 KiB
Vue
Raw Normal View History

2024-08-20 12:11:31 +00:00
<template>
<div>
<cb-detail v-if="detaildialogVisible" :data="detail" @goBack="detaildialogVisible = false">
<template v-slot:item_container>
<cb-detail-item label="密钥名称">{{ detail.name }}</cb-detail-item>
<cb-detail-item label="所属平台">{{ detail.vendorName }}</cb-detail-item>
<cb-detail-item label="指纹">{{ detail.fingerprint }}</cb-detail-item>
<cb-detail-item label="可用区">{{ detail.regionName }}</cb-detail-item>
</template>
<el-tabs value="second">
<el-tab-pane label="公钥" name="second">
2024-08-21 01:17:14 +00:00
<div style="width: 100%; word-break: break-all">
2024-08-20 12:11:31 +00:00
{{ detail.publicKey }}
</div>
</el-tab-pane>
</el-tabs>
</cb-detail>
<el-dialog title="新增密钥" :visible.sync="addFlag" width="40%" :before-close="handleClose">
<cb-form ref="addData" :model="addData">
<cb-form-item label="创建方式">
<div class="vm-region region-box" :class="{ true: 'region-active' }[row.isRegionActive]" @click="chooseRegion1(row)" v-for="row in createWays" :key="row.id">
<span class="region-txt">{{ row.name }}</span>
</div>
</cb-form-item>
2024-08-21 01:17:14 +00:00
<cb-form-item label="可用地域" prop="regionId" :rules="[required]">
<el-select v-model="addData.regionId" @change="getZone">
<el-option v-for="(item, index) in regionData" :key="index" :label="item.name" :value="item.regionId"></el-option>
</el-select>
</cb-form-item>
<cb-form-item label="可用区域" prop="zoneId" :rules="[required]">
<el-select v-model="addData.zoneId">
<el-option v-for="(item, index) in zoneList" :key="index" :label="item.name" :value="item.zoneId"></el-option>
</el-select>
</cb-form-item>
<cb-form-item label="名称" prop="name" :rules="[required, hicNoChinese]" required-message="">
2024-08-20 12:11:31 +00:00
<el-input v-model="addData.name"></el-input>
</cb-form-item>
<cb-form-item label="公钥" v-if="way == 'daoru'" prop="publicKey" :rules="[required]" required-message="请输入公钥" :maxlength="10000">
<el-input type="textarea" v-model="addData.publicKey"></el-input>
</cb-form-item>
<cb-form-item label="读取文件" v-if="way == 'daoru'">
<input type="file" class="file" ref="file" @change="change" />
</cb-form-item>
</cb-form>
<div slot="footer" class="dialog-footer">
<el-button type="ghost" @click="cancel('addData')"> </el-button>
<el-button type="primary" @click="addOk('addData')"> </el-button>
</div>
</el-dialog>
<el-card class="wrapper" v-if="!detaildialogVisible">
<cb-advance-table :card-border="false" title="秘钥列表" :search-configs="searchConfigs" :data="list" :params="params" :columns="columns" :get-list="getData" :total="total" :loading="loading" @selection-change="selectionChange">
<template v-slot:action>
2024-08-21 01:17:14 +00:00
<el-button type="primary" @click="add"> </el-button>
2024-08-20 12:11:31 +00:00
</template>
<template #name="val, record">
<span class="detail-href" @click="getDetail(record.id)">{{ record.name }}</span>
</template>
2024-08-21 01:17:14 +00:00
<template #operate="val, record">
2024-08-20 12:11:31 +00:00
<el-button :disabled="record.disabled" type="text" @click="dropdownClick({ id: record.id })"> <i class="el-icon-delete"></i> 删除 </el-button>
</template>
</cb-advance-table>
</el-card>
</div>
</template>
<script>
/* global $ */
import validate from '@/validate'
import { getRegion, getZone } from 'services/platform/index'
import { getKey, removeKey, createKey, detailKey, existKey, removeKeys } from 'views/resource/ctstack/services/key'
import { downloadFile } from '@cmp/cmp-common/utils/'
const detailSetting = {
type: 'miyao',
columns: [
[
{ name: '密钥名称', value: 'name' },
{ name: '所属平台', value: 'vendorName' },
{ name: '指纹', value: 'fingerprint' }
],
[{ name: '可用区', value: 'regionName' }]
]
}
export default {
props: {
platformObject: {
type: Object,
2024-08-21 01:17:14 +00:00
default: function () {
2024-08-20 12:11:31 +00:00
return {
vendorId: -1,
operate: -1
}
}
}
},
data() {
return {
required: validate.required,
hicNoChinese: validate.hicNoChinese,
detailSetting,
detaildialogVisible: false,
detail: {},
addFlag: false,
addData: {
name: '',
vendorId: this.platformObject.vendorId,
publicKey: ''
},
params: {
page: 1,
rows: 10
},
searchData: {
name: '',
regionId: ''
},
list: [],
total: 0,
createWays: [
{ name: '创建密钥', value: 'create', isRegionActive: true },
{
name: '导入密钥',
value: 'daoru',
isRegionActive: false
}
],
way: 'create',
regionData: [],
regionList: [],
idList: [],
selectList: [],
searchConfigs: [
{ type: 'Input', value: 'name', label: '名称' },
{ type: 'Select', data: [], value: 'regionId', label: '所属地域', props: { value: 'regionId' } },
{ type: 'Const', value: 'vendorId', initValue: this.platformObject.vendorId }
],
columns: [
{
label: '密钥名称',
prop: 'name',
scopedSlots: { customRender: 'name' }
},
{
label: '所属平台',
prop: 'vendorName'
},
{
label: '指纹',
prop: 'fingerprint'
},
{
label: '操作',
disabled: true,
width: '100px',
scopedSlots: { customRender: 'operate' }
}
],
loading: false,
zoneList: []
}
},
methods: {
selectionChange(val) {
this.selectList = val
},
handleDelete() {
this.refreshId()
const list = this.idList
if (list.length == 0) return this.$message.error('请选择VPC')
this.$confirm('此操作将删除所选密钥, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeKeys(list).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getData()
this.selectList = []
}
})
})
},
refreshId() {
this.idList = []
this.selectList.forEach(item => {
this.idList.push(item.id)
})
},
// 单选
handleSelectItem(selection, row) {
this.refreshId()
if (this.idList.indexOf(row.id) > -1) {
for (let j = 0; j < this.selectList.length; j++) {
const item = this.selectList[j]
if (item.id == row.id) {
this.selectList.splice(j, 1)
break
}
}
} else {
this.selectList.push(row)
}
},
// 全选
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
}
}
}
})
}
},
// 导入密钥
change() {
const that = this
const data = this.$refs.file.files[0]
// 对文件大小和类型进行过滤
const arr = data.name.split('.')
if (['pem', 'pub'].indexOf(arr[arr.length - 1]) == -1) {
this.$notify({
title: '提示',
message: '请上传此类型的文件,【.pem.pub】',
type: 'error'
})
return
}
if (data.size > 1024 * 1024) {
this.$notify({
title: '提示',
message: '文件大小超过1M',
type: 'error'
})
return
}
if (data) {
// 将文件进行转码转换为text
const reader = new FileReader()
reader.readAsText(data)
2024-08-21 01:17:14 +00:00
reader.onload = function (f) {
2024-08-20 12:11:31 +00:00
const data = this.result
that.addData.publicKey = data
}
}
},
// 详情
getDetail(id) {
this.detaildialogVisible = true
detailKey(id).then(data => {
if (data.success) {
this.detail = data.data
}
})
},
chooseRegion1(item) {
this.addData = {
name: this.addData.name,
vendorId: this.platformObject.vendorId,
regionId: this.addData.regionId,
zoneId: this.addData.zoneId,
publicKey: ''
}
this.way = item.value
this.createWays.forEach((data, index) => {
data.isRegionActive = false
if (data.name == item.name) {
data.isRegionActive = !item.isRegionActive
}
})
},
handleClose(done) {
this.cancel('addData')
},
add() {
this.addFlag = true
getRegion({ vendorId: this.platformObject.vendorId }).then(data => {
if (data.success) {
this.regionData = data.data
}
})
this.addData = {
name: '',
vendorId: this.platformObject.vendorId,
publicKey: ''
}
this.way = 'create'
this.createWays[0].isRegionActive = true
this.createWays[1].isRegionActive = false
},
addOk(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
existKey({
condition: JSON.stringify({
condition: 'exist',
name: this.addData.name,
vendorId: this.platformObject.vendorId
})
}).then(data => {
if (data.success) {
if (this.way == 'create') {
createKey(this.addData).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.cancel('addData')
this.getData()
downloadFile('/cmp/plugins/ctstack/v1/keypairs/download', {
id: data.data
})
}
})
} else {
createKey(this.addData).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getData()
this.cancel('addData')
}
})
}
}
})
} else {
return false
}
})
},
dropdownClick(command) {
this.$confirm('此操作将永久删除该密钥, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeKey(command.id).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getData()
}
})
})
},
getData() {
this.loading = true
getKey(this.params).then(data => {
if (data.success) {
this.list = data.data.rows
this.loading = false
this.selectList = []
this.total = data.data.total
this.list.forEach(item => {
if (item.projectVisibility && item.projectVisibility != 'GLOBAL_PROJECT') {
item.disabled = true
}
})
}
})
},
handleSizeChange(val) {
this.params.rows = val
this.getData()
},
cancel(formName) {
this.addFlag = false
this.$refs[[formName]].resetFields()
},
// 获取域
getRegion() {
getRegion({ vendorId: this.platformObject.vendorId }).then(data => {
if (data.success) {
this.regionList = data.data
this.searchConfigs[1].data = data.data
}
})
},
getZone() {
this.addData.zone = ''
getZone({
vendorId: this.platformObject.vendorId,
regionId: this.addData.regionId
}).then(data => {
if (data.success) {
this.zoneList = data.data
}
})
}
},
mounted() {
this.getRegion()
},
watch: {
platformObject: {
handler(newVal, oldVal) {
this.searchConfigs = [
{ type: 'Input', value: 'name', label: '名称' },
{ type: 'Select', data: [], value: 'regionId', label: '所属地域' },
{ type: 'Const', value: 'vendorId', initValue: newVal.vendorId }
]
this.getRegion()
},
deep: true
}
}
}
</script>
<style>
.no-searchBox {
padding: 10px;
}
.vm-region {
height: 42px;
width: 110px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin: 0 10px 0 0;
border: 1px solid #ddd;
line-height: 42px;
font-size: 12px;
text-align: center;
color: #666;
cursor: pointer;
border-radius: 0;
display: inline-block;
}
.vm-region:hover {
border-color: #43bfe3 !important;
}
.vm-region-text {
border-color: #43bfe3 !important;
}
.region-active {
background-color: deepskyblue;
color: #fff;
}
</style>