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

473 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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">
<div style="width: 100%; word-break: break-all">
{{ 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>
<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="请输入名称">
<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>
<el-button type="primary" @click="add"> 新增 </el-button>
</template>
<template #name="val, record">
<span class="detail-href" @click="getDetail(record.id)">{{ record.name }}</span>
</template>
<template #operate="val, record">
<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,
default: function () {
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)
reader.onload = function (f) {
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.selectList = []
this.total = data.data.total
this.list.forEach(item => {
if (item.projectVisibility && item.projectVisibility != 'GLOBAL_PROJECT') {
item.disabled = true
}
})
}
})
.finally(() => {
this.loading = false
})
},
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>