cmc-web/webs/cms-web/src/views/compute/vm.vue

594 lines
24 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>
<el-card class="wrapper">
<div v-if="!detailFlag">
<el-form :inline="true">
<el-form-item>
<el-input class="search-item" placeholder="名称" v-model="listQuery.name"></el-input>
</el-form-item>
<el-form-item>
<el-input class="search-item" placeholder="IP" v-model="listQuery.privateIps"></el-input>
</el-form-item>
<el-form-item>
<!-- <el-cascader placeholder="租户" v-model="listQuery.tenantId" :options="tenantList" clearable :props="{ emitPath: false, value: 'id', label: 'name', children: 'children' }"></el-cascader> -->
<el-select v-model="listQuery.tenantId" @change="handleSearch" clearable placeholder="租户" filterable>
<el-option v-for="item in tenantList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="listQuery.projectId" @change="handleSearch" clearable placeholder="项目" filterable>
<el-option v-for="item in projectList" :key="item.value" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="listQuery.vendorId" @change="handleSearch" clearable placeholder="平台" filterable>
<el-option v-for="item in platformData" :key="item.value" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="listQuery.dcId" @change="handleSearch" placeholder="数据中心" clearable>
<el-option v-for="item in dcList" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="listQuery.status" @change="handleSearch" clearable placeholder="请选择状态">
<el-option v-for="item in statusData" :key="item.value" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="ghost" class="el-icon-search" @click="handleSearch">搜索</el-button>
<el-button type="ghost" class="el-icon-refresh" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<cb-advance-table title="" :data="list" :params="params" :columns="columns" :get-list="getList" :total="total" :loading="loading" @select="handleSelectItem" @select-all="handleSelectAll" ref="resourceMonitorTable">
<template #name="val, record">
<span class="detail-href" @click="getDetail(record)">{{ val }}</span>
</template>
<template #privateIps="privateIps, record">
<div v-if="record.vendorType == 'OPENSTACK' || record.vendorType == 'EASYSTACK' || record.vendorType == 'MANAGEONE' || record.vendorType == 'FUSIONCLOUD'">
<span v-for="item in record.privateIps" :key="item.networkId">
<div v-for="(items1, index) in item.addresses" :key="index">{{ items1.address ? '(内网)' : '' }}{{ items1.address + (!item.networkName ? '' : '(' + item.networkName + ')') }}</div>
</span>
</div>
<div v-else-if="record.vendorType == 'VMWARE' || record.vendorType == 'POWERVC'">
<div v-for="item in record.privateIps" :key="item.address">{{ item.address ? '(内网)' : '' }}{{ !item.address ? '' : item.address + (!item.networkName ? '' : '(' + item.networkName + ')') }}</div>
</div>
<div v-else-if="record.vendorType == 'HUAWEI' || record.vendorType == 'HCSO'">
<div v-for="item in record.privateIps" :key="item.address">{{ item.type == 'floating' ? '(公网)' : '(内网)' }}{{ !item.address ? '' : item.address + (!item.networkName ? '' : '(' + item.networkName + ')') }}</div>
</div>
<div v-else-if="record.vendorType == 'QCLOUD' || record.vendorType == 'CNWARE' || record.vendorType == 'KINGCLOUD'">
<div v-for="(item, index) in record.privateIps" :key="index">(内网){{ item.address }}</div>
</div>
<div v-else-if="record.vendorType == 'ZSTACK' || record.vendorType == 'SMARTX'">
<div v-for="(item, index) in record.privateIps" :key="index">(内网){{ item.ip }}</div>
</div>
<div v-else-if="record.vendorType == 'AZURE' || record.vendorType == 'AWS'">
<div v-for="item in record.privateIps" :key="item">(内网){{ item }}</div>
</div>
<div v-else-if="record.vendorType == 'JDCLOUD'">
<div v-for="(item, index) in record.privateIps" :key="index">(内网){{ item }}</div>
</div>
<div v-else-if="record.vendorType == 'CAS'">
<div v-for="(item, index) in record.privateIps" :key="index">{{ item.ipAddr }}</div>
</div>
<div v-else-if="record.vendorType == 'HWACCESS'">
<div>{{ record.managerIp }}</div>
</div>
<div v-else-if="record.vendorType == 'VOLCENGINE'">
<!-- <div v-for="(item, index) in record.privateIps" :key="index">(内网){{ item.primaryIpAddress }}</div> -->
<div v-if="JSON.parse(record.privateIps)[0].primaryIpAddress">{{ JSON.parse(record.privateIps)[0].primaryIpAddress }}(内网)</div>
<div v-if="JSON.parse(record.privateIps)[0].eipAddress">{{ JSON.parse(record.privateIps)[0].eipAddress }}(公网)</div>
</div>
<div v-else>
<div v-for="item in record.privateIps" :key="item">(内网){{ item }}</div>
</div>
<div v-if="record.floatingIp">(公网){{ record.floatingIp }}</div>
<div v-if="record.vendorType == 'TENCENT' || record.vendorType == 'ALIYUN' || record.vendorType == 'AZURE' || record.vendorType == 'AWS' || record.vendorType == 'QCLOUD' || record.vendorType == 'KINGCLOUD' || record.vendorType == 'CTSTACK'">
<div v-for="(item, index) in record.publicIps" :key="index">(公网){{ item }}</div>
</div>
</template>
<template #status="status">
<cb-status-icon :type="vmStatusColorFilter(status)">
{{ openstackServerFilter(status) }}
</cb-status-icon>
</template>
<template #spec="val, record"> {{ (record.cpu ? record.cpu : 0) + 'C/' + (record.memory ? record.memory : 0) + 'GB/' }}{{ record.disk == null ? 0 : record.disk + 'GB' }} </template>
<template #system="val, record">
<div v-if="record.vendorType == 'VMWARE' || record.vendorType == 'TIANYI' || record.vendorType == 'HUAWEI'">
{{ record.osName ? record.osName : record.osCategory }}
</div>
<div v-else>
{{ (record.osCategory ? record.osCategory : '') + ' ' + (record.osName ? record.osName : '') + ' ' + (record.osVersion ? record.osVersion : '') }}
</div>
</template>
<template #cpuUsage="cpuUsage">
<el-progress class="progress" :color="customColorMethod" text-inside :stroke-width="16" :percentage="cpuUsage ? cpuUsage : 0"></el-progress>
</template>
<template #memUsage="memUsage">
<el-progress class="progress" :color="customColorMethod" text-inside :stroke-width="16" :percentage="memUsage ? memUsage : 0"></el-progress>
</template>
<template #operate="val, record">
<cb-link @click="handleMonitorDetail(record)"> 告警详情</cb-link>
<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="handleLink(record)"> 关联规则 </el-dropdown-item>
<el-dropdown-item @click.native="handlePolicy(record)">
{{ `${record.alarmEnable ? '屏蔽' : '开启'}告警` }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</cb-advance-table>
<add-policy v-if="addFlag" :resourceType="resourceType" @cancle="cancle" :add-link-flag="addFlag" :resourceId="resourceId" :ruleGroupIds="ruleGroupIds"></add-policy>
<cb-dialog title="设置监控IP" :visible.sync="setIPFlag" v-if="setIPFlag" @ok="setSubmit">
<el-row>
<cb-form ref="setData" :model="setData" :cb-status-icon="true">
<el-col :span="24">
<cb-form-item label="IP地址" prop="ip" validate="required">
<el-select clearable v-model="setData.ip">
<el-option v-for="(item, index) in ipData" :key="index" :label="item.address" :value="item.address"></el-option>
</el-select>
</cb-form-item>
</el-col>
</cb-form>
</el-row>
</cb-dialog>
</div>
<cb-detail v-if="detailFlag" :title="detailData.name" @goBack="goBack">
<div slot="custom_content">
<aliyun-detail v-if="detailData.vendorType == 'ALIYUN'" :detail-id="detailId" :instance-id="instanceId"></aliyun-detail>
<openstack-detail v-if="detailData.vendorType == 'OPENSTACK'" :detail-id="detailId" :instance-id="instanceId"></openstack-detail>
<vcenter-detail v-if="detailData.vendorType == 'VMWARE'" :detail-id="detailId" :identifier="identifier" :host-name="hostName" :bios-uuid="biosUuid"></vcenter-detail>
<huawei-detail v-if="detailData.vendorType == 'HUAWEI'" :detail-id="detailId" :instance-id="instanceId"></huawei-detail>
<hwaccess-detail v-if="detailData.vendorType == 'HWACCESS'" :detail-id="detailId" :instance-id="instanceId"></hwaccess-detail>
<aliyun-detail v-if="detailData.vendorType == 'TCE'" :detail-id="detailId" :instance-id="instanceId" :tceData="{ type: 'TCE', vendorId: detailData.vendorId, vendorName: detailData.vendorName }"></aliyun-detail>
<easystack-detail v-if="detailData.vendorType == 'EASYSTACK'" :detail-id="detailId" :instance-id="instanceId"></easystack-detail>
<hcso-detail v-if="detailData.vendorType == 'HCSO'" :detail-id="detailId" :instance-id="instanceId"></hcso-detail>
<h3c-detail v-if="detailData.vendorType == 'CAS'" :detail-id="detailId" :instance-id="instanceId" :params-str="paramsStr"></h3c-detail>
<kvm-detail v-if="detailData.vendorType == 'KVM'" :detail-id="detailId" :instance-id="instanceId"></kvm-detail>
<zstack-detail v-if="detailData.vendorType == 'ZSTACK'" :detail-id="detailId" :instance-id="instanceId"></zstack-detail>
<cnware-detail v-if="detailData.vendorType == 'CNWARE'" :detail-id="detailId" :instance-id="instanceId"></cnware-detail>
<aws-detail v-if="detailData.vendorType == 'AWS'" :detail-id="detailId" :instance-id="instanceId"></aws-detail>
<abstack-detail v-if="detailData.vendorType == 'ABCSTACK'" :detail-id="detailId" :instance-id="instanceId"></abstack-detail>
<king-detail v-if="detailData.vendorType == 'KINGCLOUD'" :detail-id="detailId" :instance-id="instanceId"></king-detail>
<smartx-detail v-if="detailData.vendorType == 'SMARTX'" :detail-id="detailId" :instance-id="detailData.localId"></smartx-detail>
<ctstack-detail v-if="detailData.vendorType == 'CTSTACK'" :detail-id="detailId" :instance-id="instanceId"></ctstack-detail>
<qing-detail v-if="detailData.vendorType == 'QCLOUD'" :vendor-id="detailData.vendorId" :instance-id="detailData.instanceId"></qing-detail>
<cloud-os-detaill v-if="detailData.vendorType == 'CLOUDOS'" :instance-id="detailData.instanceId"></cloud-os-detaill>
<el-card v-if="detailData.vendorType == 'APSARASTACK'">
<el-tabs v-model="activeTab">
<el-tab-pane v-for="(tab, index) in Object.keys(vmData)" :key="index" :name="`${index + 1}`" :label="tab">
<apsarastack-detail :detail-id="detailData.id" :instance-id="detailData.instanceId" :typeData="vmData[tab]" v-if="activeTab == index + 1" />
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</cb-detail>
</el-card>
</template>
<script>
import { vmStatusColorFilter, openstackServerFilter } from '@/filters/index'
import { getVmsByDc, setIps, getRuleGroupBind } from 'services/monitor/index.js'
import { getTenant } from '@cmp/cmp-api/system/tenant'
import { getProject } from '@cmp/cmp-api/system/project'
import { conditionCloudVendor, getDc } from 'services/platform/index'
import aliyunDetail from './cloud/aliyun/detail.vue'
import ctstackDetail from './cloud/ctstack/detail.vue'
import openstackDetail from './cloud/openstack/vm_detail.vue'
import easystackDetail from './cloud/openstack/vm_detail_easystack'
import vcenterDetail from './cloud/vcenter/vm_detail.vue'
import huaweiDetail from './cloud/huawei/detail.vue'
import hcsoDetail from './cloud/huawei/hcso_detail.vue'
import h3cDetail from './cloud/h3c/vm_detail.vue'
import kvmDetail from './cloud/kvm/vm_detail.vue'
import zstackDetail from './cloud/zstack/VmDetail.vue'
import cnwareDetail from './cloud/cnware/VmDetail.vue'
import apsarastackDetail from './cloud/apsarastack/detail.vue'
import awsDetail from './cloud/aws/detail.vue'
import hwaccessDetail from './cloud/huawei/vm_hwaccess_detail.vue'
import abstackDetail from './cloud/abc/detail.vue'
import kingDetail from './cloud/KingCloud/VmDetail.vue'
import smartxDetail from './cloud/smartx/VmDetail.vue'
import QingDetail from './cloud/qcloud/QcloudVmDetail.vue'
import CloudOsDetail from './cloud/cloudos/vm_detail.vue'
import { customColorMethod, handleStart } from 'views/data'
import addPolicy from 'views/components/linkPolicy'
import { vmData } from './cloud/apsarastack/data'
import { getMonitorList } from '@/services/monitor/configs'
import { handleSearchParam } from '@cmp/cmp-element'
const columns = [
{
type: 'selection',
disabled: true
},
{
label: '名称',
prop: 'name',
scopedSlots: { customRender: 'name' }
},
{
label: 'IP',
prop: 'privateIps',
scopedSlots: { customRender: 'privateIps' }
},
{
label: '平台',
prop: 'vendorType'
},
{
label: '状态',
prop: 'status',
scopedSlots: { customRender: 'status' }
},
{
label: '规格',
prop: 'spec',
scopedSlots: { customRender: 'spec' }
},
{
label: '操作系统',
prop: 'system',
scopedSlots: { customRender: 'system' }
},
{
label: 'CPU利用率',
prop: 'cpuUsage',
scopedSlots: { customRender: 'cpuUsage' }
},
{
label: '内存利用率',
prop: 'memUsage',
scopedSlots: { customRender: 'memUsage' }
},
{
label: '所属租户',
prop: 'tenantName'
},
{
label: '所属项目',
prop: 'projectName'
},
{
label: '操作',
disabled: true,
prop: 'id',
width: '160px',
scopedSlots: { customRender: 'operate' }
}
]
export default {
components: {
ctstackDetail,
aliyunDetail,
openstackDetail,
vcenterDetail,
huaweiDetail,
addPolicy,
easystackDetail,
hcsoDetail,
h3cDetail,
kvmDetail,
zstackDetail,
cnwareDetail,
apsarastackDetail,
awsDetail,
hwaccessDetail,
abstackDetail,
kingDetail,
smartxDetail,
QingDetail,
CloudOsDetail
},
data() {
return {
vmStatusColorFilter,
openstackServerFilter,
listQuery: {
name: ''
},
statusData: [
{ value: 'RUNNING', name: '运行中' },
{ value: 'BUILDING', name: '创建中' },
{ value: 'STOPPED', name: '关机' },
{ value: 'SUSPENDED', name: '挂起' },
{ value: 'EXCEPTION', name: '异常' },
{ value: 'UNKNOWN', name: '断开' }
],
tenantList: [],
projectList: [],
platformData: [],
columns,
customColorMethod,
handleStart,
params: {
page: 1,
rows: 10
},
list: [],
total: 0,
idList: [],
selectList: [],
detailFlag: false,
detailId: null,
instanceId: '',
setData: {},
ipData: [],
setIPFlag: false,
loading: false,
identifier: '',
hostName: '',
biosUuid: '',
addFlag: false,
resourceId: 0,
ruleGroupIds: [],
resourceType: '',
activeTab: '1',
vmData,
dcList: []
}
},
computed: {
paramsStr() {
const { uuid, name, managerIp } = this.detailData
return `id = "${uuid}", ip = "${managerIp}",name = "${name}"`
}
},
methods: {
goBackCloud() {
history.go(-1)
},
getList() {
this.refreshId()
this.loading = true
const cloneParams = JSON.parse(this.params.params)
console.log(cloneParams)
// 转换参数格式
const convertedParams = []
cloneParams.forEach((item) => {
const paramKeys = Object.keys(item.param)
paramKeys.forEach((key) => {
convertedParams.push({
param: { [key]: item.param[key] },
sign: item.sign
})
})
})
const params = {
...this.params,
params: JSON.stringify(convertedParams)
}
getVmsByDc(params).then((data) => {
this.loading = false
if (data.success) {
this.list = data.data.rows
this.total = data.data.total
this.list.forEach((item) => {
item.cpuUsage = Number(item.cpuUsage)
item.memUsage = Number(item.memUsage)
if (item.privateIps && this.IsJsonString(item.privateIps)) {
item.privateIps = JSON.parse(item.privateIps)
}
if (item.publicIps && this.IsJsonString(item.publicIps)) {
item.publicIps = JSON.parse(item.publicIps)
}
switch (item.onOffStatus) {
case '0':
item.onOffStatus = '断开'
break
case '1':
item.onOffStatus = '正常'
break
default:
item.onOffStatus = '未知'
break
}
const self = this
setTimeout(function () {
if (self.idList.indexOf(item.id) > -1) self.$refs.resourceMonitorTable.toggleRowSelection(item, true)
})
})
}
})
},
IsJsonString(str) {
try {
JSON.parse(str)
} catch (e) {
return false
}
return true
},
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
}
}
}
})
}
},
refreshId() {
this.idList = []
this.selectList.forEach((item) => {
this.idList.push(item.id)
})
},
handleSearch() {
this.params.page = 1
this.params.params = handleSearchParam({
'privateIps:lk': this.listQuery.privateIps,
'name:lk': this.listQuery.name,
isTemplate: false,
tenantId: this.listQuery.tenantId || '',
projectId: this.listQuery.projectId || '',
vendorId: this.listQuery.vendorId || '',
status: this.listQuery.status || '',
dcId: this.listQuery.dcId || ''
})
this.getList()
},
handleReset() {
this.listQuery = {}
this.selectList = []
this.handleSearch()
},
getPlatformData() {
conditionCloudVendor({
condition: JSON.stringify({
condition: 'listByTypes',
types: ['KVM', 'OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'TIANYI', 'HUAWEI', 'CAS', 'ALIYUN', 'TCE', 'ABCSTACK', 'AWS', 'HCSO', 'EASYSTACK', 'HWACCESS', 'APSARASTACK', 'FUSIONSPHERE', 'ZSTACK', 'CNWARE', 'KINGCLOUD', 'SMARTX', 'CTSTACK']
})
}).then((data) => {
if (data.success) {
this.platformData = data.data
}
})
},
getTenantList() {
getTenant({
// condition: JSON.stringify({
// condition: 'listTopOrganization',
// isTree: true
// })
page: 1,
rows: 9999
}).then((data) => {
if (data.success) {
this.tenantList = data.data.rows
}
})
},
getDc() {
getDc({ simple: true }).then((res) => {
if (res.success) {
this.dcList = res.data.rows
}
})
},
getProject() {
getProject({
page: 1,
rows: 9999
}).then((data) => {
if (data.success) {
this.projectList = data.data.rows
}
})
},
handleLink(data) {
this.ruleGroupIds = []
this.resourceId = data.id
this.resourceType = data.vendorType == 'VMWARE' ? 'MONITOR_VCENTER_VM' : data.vendorType == 'TCE' ? `MONITOR_${data.vendorType}_CVM` : `MONITOR_${data.vendorType}_VM`
getRuleGroupBind(data.id).then((data) => {
if (data.success) {
this.ruleGroupIds = data.data
this.addFlag = true
}
})
},
cancle() {
this.addFlag = false
this.getList()
},
handlePolicy(data) {
this.resourceType = data.vendorType == 'VMWARE' ? 'MONITOR_VCENTER_VM' : data.vendorType == 'TCE' ? `MONITOR_${data.vendorType}_CVM` : `MONITOR_${data.vendorType}_VM`
this.handleStart(this, data, this.resourceType)
},
getDetail(row) {
this.detailId = row.id
this.instanceId = row.instanceId
this.identifier = row.name
this.hostName = row.hostName
this.biosUuid = row.biosUuid
this.detailData = Object.assign({}, row)
this.detailFlag = true
},
goBack() {
this.detailFlag = false
},
handleMonitorDetail(data) {
this.resourceType = data.vendorType == 'VMWARE' ? 'MONITOR_VCENTER_VM' : data.vendorType == 'TCE' ? `MONITOR_${data.vendorType}_CVM` : `MONITOR_${data.vendorType}_VM`
this.$router.push({
name: 'MonitorDetailList',
query: { id: data.id, name: data.name, type: this.resourceType }
})
},
setIP(row) {
this.setData = {
id: row.id,
ip: row.monitorIp
}
this.ipData = row.privateIps
this.setIPFlag = true
},
setSubmit() {
this.$refs.setData.validate((valid) => {
if (valid) {
setIps(this.setData).then((data) => {
this.$notify({
message: data.message,
type: 'success'
})
this.setIPFlag = false
this.getList()
})
}
})
},
async getQuotas() {
const { data } = await getMonitorList({ page: 1, rows: 9999, params: '[{"param":{"resourceType":"MONITOR_APSARASTACK_VM"},"sign":"EQ"}]' })
Object.keys(vmData).forEach((key) => {
vmData[key].forEach((item) => {
if (data.rows.find((row) => row.expr == item.value)) {
const { name, unit } = data.rows.find((row) => row.expr == item.value)
item.name = `['${name}']`
item.unit = unit
item.title = name
}
})
})
}
},
created() {
this.handleSearch()
this.getTenantList()
this.getProject()
this.getPlatformData()
this.getQuotas()
this.getDc()
}
}
</script>
<style scoped></style>