forked from JointCloud/JCC-RIP
merge from primary branch
This commit is contained in:
parent
cdb24ade09
commit
2316e37d83
|
@ -3,6 +3,6 @@ ENV = 'production'
|
||||||
|
|
||||||
# base api
|
# base api
|
||||||
VUE_APP_BASE_API = 'prod-api'
|
VUE_APP_BASE_API = 'prod-api'
|
||||||
VUE_APP_FUNCTION_API = 'api'
|
VUE_APP_FUNCTION_API = 'apis/v1'
|
||||||
VUE_APP_PUBLIC_SOURCE_API = '/monitor'
|
VUE_APP_PUBLIC_SOURCE_API = '/monitor'
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ export function putHostYaml(name, yaml) {
|
||||||
// 虚拟机管理-虚拟机列表
|
// 虚拟机管理-虚拟机列表
|
||||||
export function getVirtualMachines() {
|
export function getVirtualMachines() {
|
||||||
return request({
|
return request({
|
||||||
url: '/virtual/v1/kubevirt.io.virtualmachine',
|
url: '/virtual/v1/harvester/kubevirt.io.virtualmachines',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,13 @@ export function deleteImage(name) {
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function editImage(name, data) {
|
||||||
|
return request({
|
||||||
|
url: '/virtual/v1/harvester/harvesterhci.io.virtualmachineimages/default/' + name,
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
export function getImagesYaml(name) {
|
export function getImagesYaml(name) {
|
||||||
return request({
|
return request({
|
||||||
url: '/virtual/apis/harvesterhci.io/v1beta1/namespaces/default/virtualmachineimages/' + name,
|
url: '/virtual/apis/harvesterhci.io/v1beta1/namespaces/default/virtualmachineimages/' + name,
|
||||||
|
@ -293,7 +300,7 @@ export function createVirtualMachine(data) {
|
||||||
|
|
||||||
export function virtualMachineACtion(name, action) {
|
export function virtualMachineACtion(name, action) {
|
||||||
return request({
|
return request({
|
||||||
url: '/virtual/v1/kubevirt.io.virtualmachines/default/' + name + '?action=' + action,
|
url: '/virtual/v1/harvester/kubevirt.io.virtualmachines/default/' + name + '?action=' + action,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: {}
|
data: {}
|
||||||
})
|
})
|
||||||
|
@ -317,14 +324,14 @@ export function getVirtualNode() {
|
||||||
|
|
||||||
export function moveVirtualNode(id, data) {
|
export function moveVirtualNode(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/virtual/v1/kubevirt.io.virtualmachines/default/${id}?action=migrate`,
|
url: `/virtual/v1/harvester/kubevirt.io.virtualmachines/default/${id}?action=migrate`,
|
||||||
method: 'Post',
|
method: 'Post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteVirtualMachine(name, data) {
|
export function deleteVirtualMachine(name, data) {
|
||||||
var newUrl = '/virtual/v1/kubevirt.io.virtualmachines/default/' + name + '?'
|
var newUrl = '/virtual/v1/harvester/kubevirt.io.virtualmachines/default/' + name + '?'
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
newUrl += 'removedDisks=' + data[i] + '&'
|
newUrl += 'removedDisks=' + data[i] + '&'
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,30 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// http://119.45.100.73:30880/api/v1/namespaces/jh-test1/configmaps
|
||||||
|
// http://119.45.100.73:30880/api/v1/namespaces/jh-test1/secrets
|
||||||
|
// 获取配置文件列表
|
||||||
|
getConfigmapList(clusterName, namespaces) {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_BASE_API + `/api${clusterName}/v1/namespaces/${namespaces}/configmaps`,
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取密钥列表
|
||||||
|
getSecretList(clusterName, namespaces) {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_BASE_API + `/api${clusterName}/v1/namespaces/${namespaces}/secrets`,
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
// 工作负载提交前check
|
// 工作负载提交前check
|
||||||
getWorkloadCheck(clusterName, namespaces, type, name) {
|
getWorkloadCheck(clusterName, namespaces, type, name) {
|
||||||
// http://10.105.20.3:30880/apis/clusters/fedjcce-ten002/apps/v1/namespaces/test-zhangjie/deployments?labelSelector=app%3Dasd
|
// http://10.105.20.3:30880/apis/clusters/fedjcce-ten002/apps/v1/namespaces/test-zhangjie/deployments?labelSelector=app%3Dasd
|
||||||
|
@ -371,34 +395,40 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 函数
|
// 函数
|
||||||
|
checkFunctionName(functionName) {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_FUNCTION_API + `/jcc-faas-manager/function/exist/${functionName}`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
},
|
||||||
createFunction(query) {
|
createFunction(query) {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/createFunction',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/createFunction',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: query
|
data: query
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
deleteFunctionByName() {
|
deleteFunctionByName() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/delete/functionByName',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/delete/functionByName',
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
deleteFunction(functionId) {
|
deleteFunction(functionId) {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + `/function/deleteFunction/${functionId}`,
|
url: process.env.VUE_APP_FUNCTION_API + `/jcc-faas-manager/function/deleteFunction/${functionId}`,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getFunctionByFunctionName() {
|
getFunctionByFunctionName() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/delete/functionByName',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/delete/functionByName',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
invokeFunction(params, query) {
|
invokeFunction(params, query) {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/invokeFunction',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/invokeFunction',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: params,
|
params: params,
|
||||||
data: query
|
data: query
|
||||||
|
@ -406,7 +436,7 @@ export default {
|
||||||
},
|
},
|
||||||
listFunctions(query) {
|
listFunctions(query) {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/lists',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/lists',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query || { page: 1, size: 10 }
|
params: query || { page: 1, size: 10 }
|
||||||
})
|
})
|
||||||
|
@ -419,41 +449,41 @@ export default {
|
||||||
// },
|
// },
|
||||||
getFunctionOverview() {
|
getFunctionOverview() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/selectFunctionOverview',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/selectFunctionOverview',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getFunctionMap() {
|
getFunctionMap() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/selectFunctionList',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/selectFunctionList',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 大屏总营收接口
|
// 大屏总营收接口
|
||||||
getRevenue() {
|
getRevenue() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/queryRevenue',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-mall/order/queryRevenue',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 大屏地球查询
|
// 大屏地球查询
|
||||||
getMapArea() {
|
getMapArea() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryByArea',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryByArea',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 大屏云厂商服务器数量查询接口
|
// 大屏云厂商服务器数量查询接口
|
||||||
getCloudServerCount() {
|
getCloudServerCount() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryByManufacturer',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryByManufacturer',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 大屏服务器数量统计接口
|
// 大屏服务器数量统计接口
|
||||||
getServerDeviceCount() {
|
getServerDeviceCount() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryDeviceCount',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryDeviceCount',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -461,7 +491,7 @@ export default {
|
||||||
// 大屏服务器数量统计接口
|
// 大屏服务器数量统计接口
|
||||||
getOrderStatus() {
|
getOrderStatus() {
|
||||||
return request({
|
return request({
|
||||||
url: process.env.VUE_APP_FUNCTION_API + '/countOrderStatus',
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-mall/order/countOrderStatus',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
// 大屏云厂商服务器数量查询接口
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getTotalName() {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryByManufacturer',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 大屏服务器数量统计接口
|
||||||
|
export function getTotalNum() {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryDeviceCount',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 大屏地球地区查询接口
|
||||||
|
export function getEarthRegion() {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryByArea',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 大屏地球各个区域服务器资源详细接口
|
||||||
|
export function getEarthDetails(area) {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_FUNCTION_API + '/jcc-faas-manager/function/device/queryResDetailByArea?area=' + area,
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CPU平均使用率接口
|
||||||
|
export function getCpuAverage(start, end, step) {
|
||||||
|
return request({
|
||||||
|
url: '/monitoringscreen/api/v1/query_range?query=avg(1%20-%20avg(rate(node_cpu_seconds_total%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%2Cmode%3D%22idle%22%7D%5B2m%5D))%20by%20(instance))%20*%20100' + '&start=' + start + '&end=' + end + '&step=' + step + '&_=1642578431700',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内存平均使用率接口
|
||||||
|
export function getRamAverage(start, end, step) {
|
||||||
|
return request({
|
||||||
|
url: '/monitoringscreen/api/v1/query_range?query=(sum(node_memory_MemTotal_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D%20-%20node_memory_MemAvailable_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D)%20%2F%20sum(node_memory_MemTotal_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D))*100' + '&start=' + start + '&end=' + end + '&step=' + step + '&_=1642578431700',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计量计费接口总价格
|
||||||
|
export function getMeasure(start, end, step) {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_BASE_API + '/kapis/clusters/host/metering.kubesphere.io/v1alpha1/cluster' + '?start=' + start + '&end=' + end + '&step=' + step + 's&metrics_filter=meter_cluster_cpu_usage%7Cmeter_cluster_memory_usage%7Cmeter_cluster_net_bytes_transmitted%7Cmeter_cluster_net_bytes_received%7Cmeter_cluster_pvc_bytes_total&resources_filter=host',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内存整体负载接口
|
||||||
|
export function getRamLoad(start, end, step) {
|
||||||
|
return request({
|
||||||
|
url: '/monitoringscreen/api/v1/query_range?query=sum(node_memory_MemTotal_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D%20-%20node_memory_MemAvailable_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D)&start=' + start + '&end=' + end + '&step=' + step + '&_=1642669327729',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计量计费列表接口
|
||||||
|
export function getMeteringList(start, end, step) {
|
||||||
|
return request({
|
||||||
|
url: process.env.VUE_APP_BASE_API + '/kapis/clusters/host/metering.kubesphere.io/v1alpha1/cluster' + '?start=' + start + '&end=' + end + '&step=' + step + 's&metrics_filter=meter_cluster_cpu_usage%7Cmeter_cluster_memory_usage%7Cmeter_cluster_net_bytes_transmitted%7Cmeter_cluster_net_bytes_received%7Cmeter_cluster_pvc_bytes_total&resources_filter=host',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CPU整体负载接口
|
||||||
|
export function getCpuAllload(start, end) {
|
||||||
|
return request({
|
||||||
|
url: '/monitoringscreen/api/v1/query_range?query=node_load15%7Binstance%3D~%22k8s-master%22%7D&start=' + start + '&end=' + end + '&step=900&_=1645409802467',
|
||||||
|
method: 'get',
|
||||||
|
data: JSON,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 添加容器镜像 -->
|
<!-- 添加容器镜像 -->
|
||||||
<!-- 初始容器 和 其他 -->
|
<!-- 初始容器 和 其他 -->
|
||||||
<el-dialog v-if="dialogVisible" width="80%" :title="(!createContainerForm.name?'添加':'编辑')+'容器'" :visible.sync="dialogVisible">
|
<el-dialog v-if="dialogVisible" width="80%" :title="(!createContainerForm.name?'添加':'编辑')+'容器'" :visible.sync="dialogVisible" append-to-body>
|
||||||
|
|
||||||
<el-form ref="createContainerForm" :model="createContainerForm">
|
<el-form ref="createContainerForm" :model="createContainerForm">
|
||||||
<div class="border">
|
<div class="border">
|
||||||
|
|
|
@ -1,29 +1,37 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 添加存储卷 -->
|
<!-- 添加存储卷 -->
|
||||||
<el-dialog v-if="dialogVisible" width="80%" title="存储卷" :visible.sync="dialogVisible">
|
<el-dialog v-if="dialogVisible" width="80%" title="存储卷" :visible.sync="dialogVisible" append-to-body>
|
||||||
<el-form ref="createVolumesForm" :model="createVolumesForm">
|
<el-form ref="volumeData" :model="volumeData">
|
||||||
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
|
||||||
<el-tab-pane label="已有存储卷" name="first">
|
<el-tab-pane label="已有存储卷" name="first">
|
||||||
<el-select v-model="createVolumesForm.volumes" class="selectPro" placeholder="选择已有存储卷">
|
<el-form-item
|
||||||
<el-option
|
v-if="activeName==='first'"
|
||||||
v-for="item in volumesList"
|
prop="firstName"
|
||||||
:key="item.label"
|
label=""
|
||||||
:label="item.label"
|
required
|
||||||
:value="item.label"
|
>
|
||||||
>
|
<el-select v-model="volumeData.firstName" class="selectPro" placeholder="选择已有存储卷">
|
||||||
<span style="width:50%; display:block;float:left">{{ item.label }}{{ item.alias?'('+item.alias+')':'' }}存储类型:{{ item.storageClassName }}</span>
|
<el-option
|
||||||
<span style="width:10%;display:block;float:left; color: #8492a6; font-size: 13px">容量:{{ item.storage }}</span>
|
v-for="item in volumesList"
|
||||||
<span style="width:40%; display:block;float:left; text-align:right">访问模式:{{ item.accessModes }}</span>
|
:key="item.label"
|
||||||
</el-option>
|
:label="item.label"
|
||||||
</el-select>
|
:value="item.label"
|
||||||
|
>
|
||||||
|
<span style="width:50%; display:block;float:left">{{ item.label }}{{ item.alias?'('+item.alias+')':'' }}存储类型:{{ item.storageClassName }}</span>
|
||||||
|
<span style="width:10%;display:block;float:left; color: #8492a6; font-size: 13px">容量:{{ item.storage }}</span>
|
||||||
|
<span style="width:40%; display:block;float:left; text-align:right">访问模式:{{ item.accessModes }}</span>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="临时存储卷" name="second">
|
<el-tab-pane label="临时存储卷" name="second">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
prop="volumesName"
|
v-if="activeName==='second'"
|
||||||
|
prop="secondName"
|
||||||
label="存储卷名称"
|
label="存储卷名称"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<el-input v-model="createVolumesForm.volumesName" :maxlength="63" />
|
<el-input v-model="volumeData.secondName" :maxlength="63" />
|
||||||
<span class="tips">最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾</span>
|
<span class="tips">最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
@ -33,19 +41,21 @@
|
||||||
type="warning"
|
type="warning"
|
||||||
/>
|
/>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
prop="volumesName"
|
v-if="activeName==='third'"
|
||||||
|
prop="thirdName"
|
||||||
label="存储卷名称"
|
label="存储卷名称"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<el-input v-model="createVolumesForm.volumesName" :maxlength="63" />
|
<el-input v-model="volumeData.thirdName" :maxlength="63" />
|
||||||
<span class="tips">最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾</span>
|
<span class="tips">最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
v-if="activeName==='third'"
|
||||||
prop="hostPath"
|
prop="hostPath"
|
||||||
label="HostPath"
|
label="HostPath"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<el-input v-model="createVolumesForm.volumesName" :maxlength="63" />
|
<el-input v-model="volumeData.path" :maxlength="63" />
|
||||||
<span class="tips">最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾</span>
|
<span class="tips">最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
@ -53,9 +63,9 @@
|
||||||
<table v-if="formData.spec.template.spec.containers">
|
<table v-if="formData.spec.template.spec.containers">
|
||||||
<tr v-for="(item, index) in formData.spec.template.spec.containers" :key="index" class="dataList">
|
<tr v-for="(item, index) in formData.spec.template.spec.containers" :key="index" class="dataList">
|
||||||
<td>容器</td>
|
<td>容器</td>
|
||||||
<td>{{ item }}</td>
|
<td>{{ item.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<el-select v-model="createVolumesForm.readOnly">
|
<el-select v-model="createVolumesForm[index].readOnly">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="it in mountOptions"
|
v-for="it in mountOptions"
|
||||||
:key="it.value"
|
:key="it.value"
|
||||||
|
@ -64,7 +74,7 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</td>
|
</td>
|
||||||
<td><el-input v-model="createVolumesForm.mountPath" :disabled="!createVolumesForm.readOnly || createVolumesForm.readOnly === 'null'" placeholder="容器挂载路径, 例如: /data" /></td>
|
<td><el-input v-model="createVolumesForm[index].mountPath" :disabled="createVolumesForm[index].readOnly == null" placeholder="容器挂载路径, 例如: /data" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
@ -77,6 +87,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mountOptions } from '@/utils/map'
|
import { mountOptions } from '@/utils/map'
|
||||||
|
import generate from 'nanoid/generate'
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
|
@ -94,7 +105,13 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createVolumesForm: {},
|
createVolumesForm: [],
|
||||||
|
volumeData: {
|
||||||
|
firstName: '',
|
||||||
|
secondName: '',
|
||||||
|
thirdName: '',
|
||||||
|
hostPath: ''
|
||||||
|
},
|
||||||
volumesList: [],
|
volumesList: [],
|
||||||
activeName: 'first',
|
activeName: 'first',
|
||||||
mountOptions
|
mountOptions
|
||||||
|
@ -126,6 +143,15 @@ export default {
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
'formData.spec.template.spec.containers': {
|
||||||
|
handler(val) {
|
||||||
|
this.createVolumesForm = []
|
||||||
|
for (let i = 0; i < this.formData.spec.template.spec.containers.length; i++) {
|
||||||
|
this.createVolumesForm.push({ readOnly: null, mountPath: '' })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
// code(val) {
|
// code(val) {
|
||||||
// this.codeData = val
|
// this.codeData = val
|
||||||
// }
|
// }
|
||||||
|
@ -141,22 +167,49 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
ok() {
|
ok() {
|
||||||
const val = {}
|
this.$refs.volumeData.validate((valid) => {
|
||||||
// 存在容器挂载
|
if (valid) {
|
||||||
// if(this.createVolumesForm.readOnly !== 'null'){
|
// 存在容器挂载
|
||||||
// this.formData.spec.template.spec.containers.forEach(e=>{
|
const newFormData = Object.assign({}, this.formData)
|
||||||
|
let newSpecVolume = {}
|
||||||
|
switch (this.activeName) {
|
||||||
|
case 'first':
|
||||||
|
newSpecVolume = {
|
||||||
|
name: `volume-${generate('0123456789abcdefghijklmnopqrstuvwxyz', 6)}`,
|
||||||
|
persistentVolumeClaim: { claimName: this.volumeData[this.activeName + 'Name'] }
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'second':
|
||||||
|
newSpecVolume = {
|
||||||
|
name: this.volumeData[this.activeName + 'Name'],
|
||||||
|
emptyDir: {}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'third':
|
||||||
|
newSpecVolume = {
|
||||||
|
name: this.volumeData[this.activeName + 'Name'],
|
||||||
|
hostPath: {
|
||||||
|
path: this.volumeData.hostPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
newFormData.spec.template.spec.containers.forEach((e, index) => {
|
||||||
|
if (this.createVolumesForm[index]?.readOnly !== null) {
|
||||||
|
if (!e.volumeMounts) { e.volumeMounts = [] }
|
||||||
|
e.volumeMounts.push({
|
||||||
|
name: newSpecVolume.name,
|
||||||
|
readOnly: this.createVolumesForm[index]?.readOnly,
|
||||||
|
mountPath: this.createVolumesForm[index]?.mountPath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
newFormData.spec.template.spec.volumes.push(newSpecVolume)
|
||||||
|
|
||||||
// })
|
this.$emit('addVolumes', newFormData)
|
||||||
// }
|
this.dialogVisible = false
|
||||||
switch (this.activeName) {
|
}
|
||||||
case 'first':
|
})
|
||||||
|
|
||||||
break
|
|
||||||
case 'second':
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.$emit('addVolumes', val)
|
|
||||||
},
|
},
|
||||||
handleClick() {}
|
handleClick() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
<template>
|
||||||
|
<!-- 配置文件和密钥 -->
|
||||||
|
<el-dialog v-if="dialogVisible" width="80%" title="配置文件和密钥" :visible.sync="dialogVisible" append-to-body>
|
||||||
|
<el-form ref="settingForm" :model="settingForm">
|
||||||
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
|
||||||
|
<el-tab-pane label="配置" name="first">
|
||||||
|
<el-form-item
|
||||||
|
v-if="activeName==='first'"
|
||||||
|
prop="firstName"
|
||||||
|
label=""
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<el-select v-model="settingForm.firstName" class="selectPro" placeholder="请选择配置文件">
|
||||||
|
<el-option
|
||||||
|
v-for="item in configmapList"
|
||||||
|
:key="item.label"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.label"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="密钥" name="second">
|
||||||
|
<el-form-item
|
||||||
|
v-if="activeName==='second'"
|
||||||
|
prop="secondName"
|
||||||
|
label=""
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<el-select v-model="settingForm.secondName" class="selectPro" placeholder="请选择配置文件">
|
||||||
|
<el-option
|
||||||
|
v-for="item in secretList"
|
||||||
|
:key="item.label"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.label"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<table v-if="formData.spec.template.spec.containers">
|
||||||
|
<tr v-for="(item, index) in formData.spec.template.spec.containers" :key="index" class="dataList">
|
||||||
|
<td>容器</td>
|
||||||
|
<td>{{ item.name }}</td>
|
||||||
|
<td>
|
||||||
|
<el-select v-model="createVolumesForm[index].readOnly">
|
||||||
|
<el-option
|
||||||
|
v-for="it in settingMountOptions"
|
||||||
|
:key="it.value"
|
||||||
|
:label="it.label"
|
||||||
|
:value="it.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</td>
|
||||||
|
<td><el-input v-model="createVolumesForm[index].mountPath" :disabled="createVolumesForm[index].readOnly == null" placeholder="容器挂载路径, 例如: /data" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button icon="el-icon-close" circle @click="dialogVisible = false" />
|
||||||
|
<el-button icon="el-icon-check" circle @click="ok" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { settingMountOptions } from '@/utils/map'
|
||||||
|
import generate from 'nanoid/generate'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
formData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
isEdit: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
createVolumesForm: [],
|
||||||
|
settingForm: {
|
||||||
|
firstName: '',
|
||||||
|
secondName: ''
|
||||||
|
},
|
||||||
|
configmapList: [],
|
||||||
|
secretList: [],
|
||||||
|
activeName: 'first',
|
||||||
|
settingMountOptions
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
clusterName() {
|
||||||
|
if (localStorage.getItem('clusterName') === 'default') {
|
||||||
|
return ''
|
||||||
|
} else {
|
||||||
|
return '/clusters/' + localStorage.getItem('clusterName')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dialogVisible: {
|
||||||
|
get() {
|
||||||
|
return this.value
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('input', value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// codeData: {
|
||||||
|
// get() {
|
||||||
|
// return this.code + ''
|
||||||
|
// },
|
||||||
|
// set(value) {
|
||||||
|
// this.$emit('code', value)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'formData.spec.template.spec.containers': {
|
||||||
|
handler(val) {
|
||||||
|
this.createVolumesForm = []
|
||||||
|
for (let i = 0; i < this.formData.spec.template.spec.containers.length; i++) {
|
||||||
|
this.createVolumesForm.push({ readOnly: null, mountPath: '' })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
// code(val) {
|
||||||
|
// this.codeData = val
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getConfigmapList()
|
||||||
|
this.getSecretList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getConfigmapList() {
|
||||||
|
this.$Api.getConfigmapList(this.clusterName, this.formData.metadata.namespace).then(res => {
|
||||||
|
const arr = res.items.map(e => { return { label: e.metadata.name } })
|
||||||
|
this.configmapList = arr
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getSecretList() {
|
||||||
|
this.$Api.getSecretList(this.clusterName, this.formData.metadata.namespace).then(res => {
|
||||||
|
const arr = res.items.map(e => { return { label: e.metadata.name } })
|
||||||
|
this.secretList = arr
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$refs.settingForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
// 存在容器挂载
|
||||||
|
const newFormData = Object.assign({}, this.formData)
|
||||||
|
let newSpecVolume = {}
|
||||||
|
switch (this.activeName) {
|
||||||
|
case 'first':
|
||||||
|
newSpecVolume = {
|
||||||
|
name: `volume-${generate('0123456789abcdefghijklmnopqrstuvwxyz', 6)}`,
|
||||||
|
configMap: { name: this.settingForm[this.activeName + 'Name'] }
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'second':
|
||||||
|
newSpecVolume = {
|
||||||
|
name: `volume-${generate('0123456789abcdefghijklmnopqrstuvwxyz', 6)}`,
|
||||||
|
secret: { secretName: this.settingForm[this.activeName + 'Name'] }
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
newFormData.spec.template.spec.containers.forEach((e, index) => {
|
||||||
|
if (this.createVolumesForm[index]?.readOnly !== null) {
|
||||||
|
if (!e.volumeMounts) { e.volumeMounts = [] }
|
||||||
|
e.volumeMounts.push({
|
||||||
|
name: newSpecVolume.name,
|
||||||
|
readOnly: this.createVolumesForm[index]?.readOnly,
|
||||||
|
mountPath: this.createVolumesForm[index]?.mountPath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
newFormData.spec.template.spec.volumes.push(newSpecVolume)
|
||||||
|
|
||||||
|
this.$emit('addSettingOrKey', newFormData)
|
||||||
|
this.dialogVisible = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleClick() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -265,10 +265,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addImage(data) {
|
addImage(data) {
|
||||||
console.log(this.editInfoForm.spec.template.spec.containers)
|
|
||||||
this.editInfoForm.spec.template.spec.containers.push(data)
|
this.editInfoForm.spec.template.spec.containers.push(data)
|
||||||
console.log(this.editInfoForm.spec.template.spec.containers.length)
|
|
||||||
// console.log(data)
|
|
||||||
this.containerForm = undefined
|
this.containerForm = undefined
|
||||||
},
|
},
|
||||||
editImage(data) {
|
editImage(data) {
|
||||||
|
@ -303,8 +300,10 @@ export default {
|
||||||
border: 1px solid #DCDFE6;
|
border: 1px solid #DCDFE6;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
padding:10px;
|
padding:10px;
|
||||||
|
line-height: 1.4em;
|
||||||
.el-button{
|
.el-button{
|
||||||
float:right;
|
float:right;
|
||||||
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.selectRadio{
|
.selectRadio{
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<mountVolumes v-if="stepNum===2" v-model="metaData" />
|
<mountVolumes v-if="stepNum===2" v-model="metaData" />
|
||||||
<advancedSettings v-if="stepNum===3" v-model="metaData" />
|
<advancedSettings v-if="stepNum===3" v-model="metaData" />
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="createFormVisible = false">取 消</el-button>
|
<el-button @click="createFormVisible = false;transformYaml()">取 消</el-button>
|
||||||
<el-button v-if="stepNum!==0" type="primary" @click="prev">上一步</el-button>
|
<el-button v-if="stepNum!==0" type="primary" @click="prev">上一步</el-button>
|
||||||
<el-button v-if="stepNum!==3" type="primary" @click="next">下一步</el-button>
|
<el-button v-if="stepNum!==3" type="primary" @click="next">下一步</el-button>
|
||||||
<el-button v-else type="primary" @click="createWorkload">创建</el-button>
|
<el-button v-else type="primary" @click="createWorkload">创建</el-button>
|
||||||
|
@ -111,6 +111,7 @@ spec:
|
||||||
this.$Api.postWorkload(this.clusterName, this.metaData.metadata.namespace, this.classification, this.metaData).then(() => {
|
this.$Api.postWorkload(this.clusterName, this.metaData.metadata.namespace, this.classification, this.metaData).then(() => {
|
||||||
this.$message.success('创建成功!')
|
this.$message.success('创建成功!')
|
||||||
this.createFormVisible = false
|
this.createFormVisible = false
|
||||||
|
this.transformYaml()
|
||||||
this.$emit('getList')
|
this.$emit('getList')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -118,6 +119,7 @@ spec:
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
transformYaml() {
|
transformYaml() {
|
||||||
|
this.stepNum = 0
|
||||||
this.metaData = JSON.parse(JSON.stringify(yaml.load(this.baseYaml), null, 2))
|
this.metaData = JSON.parse(JSON.stringify(yaml.load(this.baseYaml), null, 2))
|
||||||
},
|
},
|
||||||
prev() {
|
prev() {
|
||||||
|
|
|
@ -1,30 +1,51 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="mountVolumes">
|
||||||
<p>挂载存储</p>
|
<p>挂载存储</p>
|
||||||
|
|
||||||
<!-- dataList -->
|
<!-- dataList -->
|
||||||
|
|
||||||
<!-- <i class="el-icon-receiving" />
|
<!-- <i class="el-icon-receiving" />
|
||||||
<i class="el-icon-setting" />
|
<i class="el-icon-setting" />
|
||||||
<i class="el-icon-key" /> -->
|
<i class="el-icon-key" /> -->
|
||||||
|
|
||||||
|
<div v-if="editInfoForm.spec.template.spec.volumes">
|
||||||
|
<div v-for="(item, index) in editInfoForm.spec.template.spec.volumes" :key="index" class="dataList">
|
||||||
|
<el-button icon="el-icon-delete" circle @click.prevent="removeVolume(index)" />
|
||||||
|
<el-button icon="el-icon-edit" circle @click.prevent="editVolume(item)" />
|
||||||
|
<div><i class="el-icon-receiving" />{{ item.name }}</div>
|
||||||
|
<div>类型:{{ item.emptyDir ? ' 临时存储卷': item.hostPath ? 'HostPath' : item.configMap ? '配置' : item.secret ? '密钥' : '已有存储卷' }}</div>
|
||||||
|
<div v-for="(it, ind) in editInfoForm.spec.template.spec.containers" :key="ind">
|
||||||
|
<div v-if="it.volumeMounts">
|
||||||
|
<div v-for="(ii, dd) in it.volumeMounts" :key="dd">
|
||||||
|
<div v-if="ii.name === item.name" class="volumeList">
|
||||||
|
<span><i class="el-icon-c-scale-to-original" />{{ it.name }}</span>
|
||||||
|
<span><i class="el-icon-reading" />{{ ii.mountPath }}({{ ii.readOnly==='true'?'只读':'读写' }})</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-button-group>
|
<el-button-group>
|
||||||
<el-button ton @click="createFormVisible=true">
|
<el-button ton @click="createFormVisible=true">
|
||||||
添加存储卷
|
添加存储卷
|
||||||
<span class="tips">支持临时存储卷以及持久化存储卷</span>
|
<span class="tips">支持临时存储卷以及持久化存储卷</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button>挂载配置文件或密钥
|
<el-button @click="mountSettingFormVisible=true">
|
||||||
|
挂载配置文件或密钥
|
||||||
<span class="tips">将配置文件或密钥挂载至指定目录</span>
|
<span class="tips">将配置文件或密钥挂载至指定目录</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
<addVolumesForm v-model="createFormVisible" :form-data="editInfoForm" @addVolumes="addVolumes" />
|
<addVolumesForm v-if="createFormVisible" v-model="createFormVisible" :form-data="editInfoForm" @addVolumes="addVolumes" />
|
||||||
|
<mountSettingForm v-if="mountSettingFormVisible" v-model="mountSettingFormVisible" :form-data="editInfoForm" @addSettingOrKey="addSettingOrKey" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import addVolumesForm from '@/components/Actions/addVolumesForm.vue'
|
import addVolumesForm from '@/components/Actions/addVolumesForm.vue'
|
||||||
|
import mountSettingForm from '@/components/Actions/mountSettingOrKey.vue'
|
||||||
export default {
|
export default {
|
||||||
components: { addVolumesForm },
|
components: { addVolumesForm, mountSettingForm },
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -34,8 +55,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createFormVisible: false,
|
createFormVisible: false,
|
||||||
createVolumesForm: {},
|
mountSettingFormVisible: false
|
||||||
formData: {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -49,12 +69,53 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addVolumes() {}
|
addSettingOrKey(e) {
|
||||||
|
this.editInfoForm = e
|
||||||
|
},
|
||||||
|
addVolumes(e) {
|
||||||
|
this.editInfoForm = e
|
||||||
|
},
|
||||||
|
editVolume() {},
|
||||||
|
removeVolume(index) {
|
||||||
|
const name = this.editInfoForm.spec.template.spec.volumes[index].name
|
||||||
|
this.editInfoForm.spec.template.spec.containers.forEach(e => {
|
||||||
|
for (let i = 0; i < e.volumeMounts?.length || 0; i++) {
|
||||||
|
if (e.volumeMounts[i].name === name) {
|
||||||
|
e.volumeMounts.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.editInfoForm.spec.template.spec.volumes.splice(index, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.mountVolumes{
|
||||||
|
.dataList{
|
||||||
|
border: 1px solid #DCDFE6;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding:10px;
|
||||||
|
line-height: 1.4em;
|
||||||
|
.el-button{
|
||||||
|
float:right;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.volumeList{
|
||||||
|
padding: 5px;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
margin-top:5px;
|
||||||
|
span{
|
||||||
|
i {display: inline-block; margin-right:10px}
|
||||||
|
display:inline-block;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.selectPro{
|
.selectPro{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { getVolume } from '@/api/one-class-page/storageManagement'
|
||||||
import { getNodeMessage, getNodeStatus } from '@/api/one-class-page/nodeManagement'
|
import { getNodeMessage, getNodeStatus } from '@/api/one-class-page/nodeManagement'
|
||||||
import { getByValue } from '@/utils/data-process'
|
import { getByValue } from '@/utils/data-process'
|
||||||
import { getDaemonSets, getDeployments, getPods, getServices, getStatefulSets } from '@/api/one-class-page/workloadManagement'
|
import { getDaemonSets, getDeployments, getPods, getServices, getStatefulSets } from '@/api/one-class-page/workloadManagement'
|
||||||
import { getUsageStatus, getVirtualHosts, getVirtualMachinesInstances, getDataVolumeNew, getImages } from '@/api/one-class-page/virtualMachine'
|
import { getUsageStatus, getVirtualHosts, getVirtualMachinesInstances, getVirtualMachines, getDataVolumeNew, getImages, getDashboardInfo, getStorageStatus } from '@/api/one-class-page/virtualMachine'
|
||||||
// import { getImages } from '@/api/one-class-page/virtualMachine'
|
// import { getImages } from '@/api/one-class-page/virtualMachine'
|
||||||
import {
|
import {
|
||||||
getBriefSystemProject,
|
getBriefSystemProject,
|
||||||
|
@ -11,6 +11,8 @@ import {
|
||||||
getDetailUserProject
|
getDetailUserProject
|
||||||
} from '@/api/one-class-page/projectManagement'
|
} from '@/api/one-class-page/projectManagement'
|
||||||
import { getHostNum, getMemberNum } from '@/api/one-class-page/cluster'
|
import { getHostNum, getMemberNum } from '@/api/one-class-page/cluster'
|
||||||
|
|
||||||
|
import { parseSi } from '@/utils'
|
||||||
// import { strToNumber } from '@/utils/data-process'
|
// import { strToNumber } from '@/utils/data-process'
|
||||||
|
|
||||||
function getStatus(readyReplicas, replicas) {
|
function getStatus(readyReplicas, replicas) {
|
||||||
|
@ -273,12 +275,25 @@ const getHostVirtualMachineList = (clusterName, params) => {
|
||||||
}
|
}
|
||||||
const getVirtualMachineList = (clusterName, params) => {
|
const getVirtualMachineList = (clusterName, params) => {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
const listResult = []
|
let listResult = []
|
||||||
getVirtualMachinesInstances().then((res) => {
|
Promise.all([
|
||||||
for (let item = 0; item < res.data.length; item++) {
|
getVirtualMachines(),
|
||||||
const obj = {}
|
getVirtualMachinesInstances()
|
||||||
obj.index = item
|
]).then(res => {
|
||||||
obj.name = res.data[item].metadata.fields[0]
|
const vm = res[0]
|
||||||
|
const vmIn = res[1]
|
||||||
|
listResult = vm.data.map((i, index) => ({
|
||||||
|
index: index,
|
||||||
|
name: i.metadata.fields[0],
|
||||||
|
state: i.metadata.annotations['harvesterhci.io/migrationState'] || i.metadata.fields[2],
|
||||||
|
operator: i.metadata.fields[5],
|
||||||
|
aliveTime: i.metadata.fields[1].replace('d', '天').replace('h', '小时'),
|
||||||
|
cpu: i.spec.template.spec.domain.resources.limits.cpu,
|
||||||
|
memory: i.spec.template.spec.domain.resources.limits.memory,
|
||||||
|
ipAddress: vmIn.data.filter(n => n.id === i.id)?.[0]?.metadata?.fields[3] || '',
|
||||||
|
node: vmIn.data.filter(n => n.id === i.id)?.[0]?.metadata?.fields[4] || '',
|
||||||
|
label: i.metadata.labels['harvesterhci.io/creator']
|
||||||
|
})
|
||||||
// TODO: 虚拟机状态显示
|
// TODO: 虚拟机状态显示
|
||||||
// var running = res.data[item].spec.running
|
// var running = res.data[item].spec.running
|
||||||
// if (running) {
|
// if (running) {
|
||||||
|
@ -286,21 +301,10 @@ const getVirtualMachineList = (clusterName, params) => {
|
||||||
// } else {
|
// } else {
|
||||||
// obj.state = 'Off'
|
// obj.state = 'Off'
|
||||||
// }
|
// }
|
||||||
obj.state = res.data[item].metadata.annotations['harvesterhci.io/migrationState'] || res.data[item].metadata.fields[2]
|
|
||||||
obj.operator = res.data[item].metadata.fields[5]
|
|
||||||
obj.aliveTime = res.data[item].metadata.fields[1]
|
|
||||||
obj.aliveTime = obj.aliveTime.replace('d', '天')
|
|
||||||
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
|
||||||
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
|
||||||
obj.cpu = res.data[item].spec.domain.cpu.cores
|
|
||||||
obj.memory = res.data[item].spec.domain.memory.guest
|
|
||||||
obj.ipAddress = res.data[item].metadata.fields[3]
|
|
||||||
obj.node = res.data[item].metadata.fields[4]
|
|
||||||
obj.label = res.data[item].metadata.labels['harvesterhci.io/creator']
|
|
||||||
// obj.memoryused = res.data[item].status.capacity.ephemeral-storage - res.data[item].status.allocatable.memory
|
// obj.memoryused = res.data[item].status.capacity.ephemeral-storage - res.data[item].status.allocatable.memory
|
||||||
// obj.memoryall = res.data[item].status.capacity.memory
|
// obj.memoryall = res.data[item].status.capacity.memory
|
||||||
listResult[item] = obj
|
// listResult[item] = obj
|
||||||
}
|
)
|
||||||
resolve({ total: 10, rows: listResult })
|
resolve({ total: 10, rows: listResult })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -309,38 +313,77 @@ const getVirtualMachineList = (clusterName, params) => {
|
||||||
const getVirtualHostList = () => {
|
const getVirtualHostList = () => {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
const listResult = []
|
const listResult = []
|
||||||
getUsageStatus().then(usage => {
|
|
||||||
getVirtualHosts().then((res) => {
|
Promise.all([
|
||||||
for (let item = 0; item < res.data.length; item++) {
|
getDashboardInfo(), // cpu 内存 总量
|
||||||
var obj = {}
|
getUsageStatus(), // cpu 内存 使用量
|
||||||
obj.index = item
|
getStorageStatus(),
|
||||||
obj.customName = res.data[item].metadata.annotations['harvesterhci.io/host-custom-name']
|
getVirtualHosts()]).then(res => {
|
||||||
obj.name = res.data[item].metadata.name
|
for (let item = 0; item < res[3].data.length; item++) {
|
||||||
obj.state = res.data[item].metadata.state.name
|
let cpuAll = 0
|
||||||
obj.state = obj.state.charAt(0).toUpperCase() + obj.state.slice(1)
|
let memoryAll = 0
|
||||||
obj.hostIP = res.data[item].metadata.fields[5]
|
let storageAll = 0
|
||||||
obj.aliveTime = res.data[item].metadata.fields[3]
|
let cpuUsed = 0
|
||||||
obj.aliveTime = obj.aliveTime.replace('d', '天')
|
let memoryUsed = 0
|
||||||
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
let storageUsage = 0
|
||||||
obj.cpuUsed = parseFloat((parseInt(usage?.data[item]?.usage?.cpu || 0) / 1000000000).toFixed(2))
|
res[0].data.forEach(element => {
|
||||||
obj.cpuAll = parseInt(res.data[item].status.capacity.cpu)
|
if (res[3].data[item].metadata.name === element.id) {
|
||||||
obj.cpuUsePercentage = parseFloat((obj.cpuUsed / obj.cpuAll).toFixed(2)) * 100
|
cpuAll += Number(element.status.capacity.cpu)
|
||||||
obj.memoryUsed = parseFloat((parseInt(usage.data[item].usage.memory) / 1024 / 1024).toFixed(2))
|
memoryAll += Number(element.status.capacity.memory.replace('Ki', ''))
|
||||||
obj.memoryAll = parseFloat((parseFloat(res.data[item].status.capacity.memory) / 1024 / 1024).toFixed(2))
|
|
||||||
obj.memoryUsePercentage = parseFloat((obj.memoryUsed / obj.memoryAll).toFixed(2)) * 100
|
|
||||||
obj.storageUsed = parseFloat((parseFloat(res.data[item].status.capacity['ephemeral-storage']) / 1024 / 1024 / 1024 - parseFloat(res.data[item].status.allocatable['ephemeral-storage']) / 1024 / 1024 / 1024 / 1024).toFixed(2))
|
|
||||||
obj.storageAll = parseFloat((parseFloat(res.data[item].status.capacity['ephemeral-storage']) / 1024 / 1024 / 1024).toFixed(2))
|
|
||||||
obj.storageUsePercentage = parseFloat((obj.storageUsed / obj.storageAll).toFixed(2)) * 100
|
|
||||||
// obj.memoryall = res.data[item].status.capacity.memory
|
|
||||||
var n, e
|
|
||||||
obj.isMaintenance = (((n = res.data[item].metadata) === null || void 0 === n || (e = n.annotations) === null || void 0 === e ? void 0 : e['harvesterhci.io/maintain-status']) === 'completed')
|
|
||||||
if (obj.isMaintenance) {
|
|
||||||
obj.state = 'Maintenance mode'
|
|
||||||
}
|
}
|
||||||
listResult[item] = obj
|
})
|
||||||
|
res[1].data.forEach(element => {
|
||||||
|
if (res[3].data[item].metadata.name === element.spec.nodeName) {
|
||||||
|
const containers = element.spec.containers || []
|
||||||
|
containers.forEach(e => {
|
||||||
|
memoryUsed += parseSi(e?.resources?.requests?.memory || '0m', { increment: 1024 })
|
||||||
|
cpuUsed += parseSi(e?.resources?.requests?.cpu || '0m')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res[2].data.forEach(element => {
|
||||||
|
if (res[3].data[item].metadata.name === element.spec.name) {
|
||||||
|
const diskStatus = element.status?.diskStatus || {}
|
||||||
|
Object.values(diskStatus).map((disk) => {
|
||||||
|
if (disk?.conditions?.Schedulable?.status === 'True' && disk?.storageAvailable && disk?.storageMaximum) {
|
||||||
|
storageUsage += (disk.storageMaximum - disk.storageAvailable)
|
||||||
|
}
|
||||||
|
if (disk?.storageMaximum) {
|
||||||
|
storageAll += disk.storageMaximum
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var obj = {}
|
||||||
|
obj.index = item
|
||||||
|
obj.customName = res[3].data[item].metadata.annotations['harvesterhci.io/host-custom-name']
|
||||||
|
obj.name = res[3].data[item].metadata.name
|
||||||
|
obj.state = res[3].data[item].metadata.state.name
|
||||||
|
obj.state = obj.state.charAt(0).toUpperCase() + obj.state.slice(1)
|
||||||
|
obj.hostIP = res[3].data[item].metadata.fields[5]
|
||||||
|
obj.aliveTime = res[3].data[item].metadata.fields[3]
|
||||||
|
obj.aliveTime = obj.aliveTime.replace('d', '天')
|
||||||
|
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
||||||
|
obj.cpuUsed = cpuUsed.toFixed(2)
|
||||||
|
obj.cpuAll = cpuAll
|
||||||
|
obj.cpuUsePercentage = (parseFloat((obj.cpuUsed / obj.cpuAll)) * 100).toFixed(0)
|
||||||
|
obj.memoryUsed = (memoryUsed / 1024 / 1024 / 1024).toFixed(2)
|
||||||
|
obj.memoryAll = (memoryAll / 1024 / 1024).toFixed(0)
|
||||||
|
obj.memoryUsePercentage = (parseFloat((obj.memoryUsed / obj.memoryAll)) * 100).toFixed(1)
|
||||||
|
obj.storageUsed = (storageUsage / 1024 / 1024 / 1024 / 1024).toFixed(2)
|
||||||
|
obj.storageAll = (storageAll / 1024 / 1024 / 1024 / 1024).toFixed(2)
|
||||||
|
obj.storageUsePercentage = (parseFloat((obj.storageUsed / obj.storageAll)) * 100).toFixed(1)
|
||||||
|
// obj.memoryall = hostRes.data[item].status.capacity.memory
|
||||||
|
var n, e
|
||||||
|
obj.isMaintenance = (((n = res[3].data[item].metadata) === null || void 0 === n || (e = n.annotations) === null || void 0 === e ? void 0 : e['harvesterhci.io/maintain-status']) === 'completed')
|
||||||
|
if (obj.isMaintenance) {
|
||||||
|
obj.state = 'Maintenance mode'
|
||||||
}
|
}
|
||||||
resolve({ total: res.data.length, rows: listResult })
|
|
||||||
})
|
listResult[item] = obj
|
||||||
|
}
|
||||||
|
resolve({ total: res[3].data.length, rows: listResult })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,3 +360,58 @@ export function newEval(str) {
|
||||||
var Fn = Function
|
var Fn = Function
|
||||||
return new Fn('return ' + str)()
|
return new Fn('return ' + str)()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UNITS = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
|
||||||
|
const FRACTIONAL = ['', 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y'] // milli micro nano pico femto
|
||||||
|
|
||||||
|
export function parseSi(inValue, opt) {
|
||||||
|
opt = opt || {}
|
||||||
|
let increment = opt.increment
|
||||||
|
const allowFractional = opt.allowFractional !== false
|
||||||
|
|
||||||
|
if (!inValue || typeof inValue !== 'string' || !inValue.length) {
|
||||||
|
return NaN
|
||||||
|
}
|
||||||
|
|
||||||
|
inValue = inValue.replace(/,/g, '')
|
||||||
|
|
||||||
|
// eslint-disable-next-line prefer-const
|
||||||
|
let [, valStr, unit, incStr] = inValue.match(/^([0-9.-]+)\s*([^0-9.-]?)([^0-9.-]?)/)
|
||||||
|
const val = parseFloat(valStr)
|
||||||
|
|
||||||
|
if (!unit) {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
// micro "mu" symbol -> u
|
||||||
|
if (unit.charCodeAt(0) === 181) {
|
||||||
|
unit = 'u'
|
||||||
|
}
|
||||||
|
|
||||||
|
const divide = FRACTIONAL.includes(unit)
|
||||||
|
const multiply = UNITS.includes(unit.toUpperCase())
|
||||||
|
|
||||||
|
if (!increment) {
|
||||||
|
// Automatically handle 1 KB = 1000B, 1 KiB = 1024B if no increment set
|
||||||
|
if ((multiply || divide) && incStr === 'i') {
|
||||||
|
increment = 1024
|
||||||
|
} else {
|
||||||
|
increment = 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (divide && allowFractional) {
|
||||||
|
const exp = FRACTIONAL.indexOf(unit)
|
||||||
|
|
||||||
|
return val / (increment ** exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiply) {
|
||||||
|
const exp = UNITS.indexOf(unit.toUpperCase())
|
||||||
|
|
||||||
|
return val * (increment ** exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unrecognized unit character
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
|
@ -17,9 +17,13 @@ const policysTypeOptions = [
|
||||||
]
|
]
|
||||||
|
|
||||||
const mountOptions = [
|
const mountOptions = [
|
||||||
{ label: '读写', value: 'false' },
|
{ label: '读写', value: false },
|
||||||
{ label: '只读', value: 'true' },
|
{ label: '只读', value: true },
|
||||||
{ label: '不挂载', value: 'null' }
|
{ label: '不挂载', value: null }
|
||||||
|
]
|
||||||
|
const settingMountOptions = [
|
||||||
|
{ label: '只读', value: true },
|
||||||
|
{ label: '不挂载', value: null }
|
||||||
]
|
]
|
||||||
|
|
||||||
const imagePullPolicyOptions = [
|
const imagePullPolicyOptions = [
|
||||||
|
@ -57,6 +61,7 @@ export {
|
||||||
policysOptions,
|
policysOptions,
|
||||||
policysTypeOptions,
|
policysTypeOptions,
|
||||||
mountOptions,
|
mountOptions,
|
||||||
|
settingMountOptions,
|
||||||
imagePullPolicyOptions,
|
imagePullPolicyOptions,
|
||||||
protocolOptions
|
protocolOptions
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<el-tab-pane label="证书查验" name="1" />
|
<el-tab-pane label="证书查验" name="1" />
|
||||||
<el-tab-pane label="身份查验" name="2" />
|
<el-tab-pane label="身份查验" name="2" />
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-input v-model="content" placeholder="请输入您想要校验的内容">
|
<el-input v-model="content" :placeholder="`${activeName === '1' ? '请输入您想要校验的内容' : '请输入身份指纹'}`">
|
||||||
<el-button slot="append" icon="el-icon-search" type="primary" @click="search">校验查询</el-button>
|
<el-button slot="append" icon="el-icon-search" type="primary" @click="search">校验查询</el-button>
|
||||||
</el-input>
|
</el-input>
|
||||||
<List
|
<List
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
<el-dialog width="70%" title="交易证书" :visible.sync="dialogCertVisible">
|
<el-dialog width="70%" title="交易证书" :visible.sync="dialogCertVisible">
|
||||||
<div class="certification">
|
<div class="certification">
|
||||||
<p>兹证明:<br>
|
<p>兹证明:<br>
|
||||||
申请人 {{ certificationData.buyerName }} 于 {{ certificationData.transTime }} 通过 {{ certificationData.sellerName }} 平台提交了以下电子数据及信息:
|
申请人 {{ certificationData.buyerName }} 于 {{ new Date(certificationData.transTime).toLocaleString() }} 通过 {{ certificationData.sellerName }} 平台提交了以下电子数据及信息:
|
||||||
</p>
|
</p>
|
||||||
<FormData :column="1" :data="certificationData" :data-map="certDataMap" />
|
<FormData :column="1" :data="certificationData" :data-map="certDataMap" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,7 +47,9 @@ export default {
|
||||||
columns: [
|
columns: [
|
||||||
{ prop: 'certNum', label: '证书编号' },
|
{ prop: 'certNum', label: '证书编号' },
|
||||||
{ prop: 'fingerPrint', label: '身份指纹' },
|
{ prop: 'fingerPrint', label: '身份指纹' },
|
||||||
{ prop: 'createDate', label: '创建时间' },
|
{ prop: 'createDate', label: '创建时间', formatter: (row) => {
|
||||||
|
return <div>{new Date(row.createDate).toLocaleString() || '-'}</div>
|
||||||
|
} },
|
||||||
{ prop: 'more', label: '操作', formatter: (row) => {
|
{ prop: 'more', label: '操作', formatter: (row) => {
|
||||||
return <div>
|
return <div>
|
||||||
<el-button onClick={() => this.viewCredential(row)} type='text' size='small'>查看</el-button>
|
<el-button onClick={() => this.viewCredential(row)} type='text' size='small'>查看</el-button>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<el-page-header content="区块列表" @back="goBack" />
|
<el-page-header content="区块列表(最近一个月的数据)" @back="goBack" />
|
||||||
<List
|
<List
|
||||||
v-if="listData.length>=1"
|
v-if="listData.length>=1"
|
||||||
ref="multipleTable"
|
ref="multipleTable"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="functionList">
|
<div class="functionList">
|
||||||
<el-button class="opr-btn" size="middle" type="primary" @click="dialogCreateVisible=true">创建函数</el-button>
|
<el-button class="opr-btn" size="middle" type="primary" @click="form={runEnv: 'python3'};dialogCreateVisible=true">创建函数</el-button>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col v-for="(item,index) in functionList" :key="index" :span="6">
|
<el-col v-for="(item,index) in functionList" :key="index" :span="6">
|
||||||
<el-card shadow="never" class="functionCard">
|
<el-card shadow="never" class="functionCard">
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
background
|
background
|
||||||
:hide-on-single-page="true"
|
:hide-on-single-page="true"
|
||||||
:current-page="page"
|
:current-page="page"
|
||||||
|
:page-size="size"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="total"
|
:total="total"
|
||||||
@current-change="currentChange"
|
@current-change="currentChange"
|
||||||
|
@ -91,15 +92,15 @@
|
||||||
<td>Function Name:</td>
|
<td>Function Name:</td>
|
||||||
<td :colspan="3">{{ form.functionName }}</td>
|
<td :colspan="3">{{ form.functionName }}</td>
|
||||||
<td>Created Time:</td>
|
<td>Created Time:</td>
|
||||||
<td>{{ form.createTime }}</td>
|
<td>{{ form.createdTime }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Env:</td>
|
<td>Env:</td>
|
||||||
<td>{{ form.runEnv }}</td>
|
<td>{{ form.runEnv }}</td>
|
||||||
<td>Memory Size:</td>
|
<td>Memory Size:</td>
|
||||||
<td>{{ form.memorySize }}</td>
|
<td>{{ form.memorySize }}MB</td>
|
||||||
<td>Timeout:</td>
|
<td>Timeout:</td>
|
||||||
<td>{{ form.timeout }}</td>
|
<td>{{ form.timeout }}s</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Code Size:</td>
|
<td>Code Size:</td>
|
||||||
|
@ -107,7 +108,7 @@
|
||||||
<td>Code Checksum:</td>
|
<td>Code Checksum:</td>
|
||||||
<td :colspan="3">{{ form.codeChecksum }}</td>
|
<td :colspan="3">{{ form.codeChecksum }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<!-- <tr>
|
||||||
<td>Description</td>
|
<td>Description</td>
|
||||||
<td :colspan="5">{{ form.description }}</td>
|
<td :colspan="5">{{ form.description }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -115,13 +116,8 @@
|
||||||
<td>EnviromentVariable:</td>
|
<td>EnviromentVariable:</td>
|
||||||
<td :colspan="2">{{ form.envVar }}</td>
|
<td :colspan="2">{{ form.envVar }}</td>
|
||||||
<td :colspan="3">
|
<td :colspan="3">
|
||||||
<!-- Enable Native Serverless:
|
|
||||||
<el-switch
|
|
||||||
v-model="form.enableNS"
|
|
||||||
size="small">
|
|
||||||
</el-switch> -->
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr> -->
|
||||||
</table>
|
</table>
|
||||||
<el-row style="margin-bottom:30px" :gutter="30">
|
<el-row style="margin-bottom:30px" :gutter="30">
|
||||||
<el-col :span="9">
|
<el-col :span="9">
|
||||||
|
@ -263,16 +259,24 @@ export default {
|
||||||
// this.form = val;
|
// this.form = val;
|
||||||
// this.activeName = '2';
|
// this.activeName = '2';
|
||||||
this.form = val
|
this.form = val
|
||||||
|
this.result = ''
|
||||||
this.dialogExecuteVisible = true
|
this.dialogExecuteVisible = true
|
||||||
},
|
},
|
||||||
createFunc() {
|
createFunc() {
|
||||||
// 新建函数
|
// 新建函数
|
||||||
const funcForm = { code: { zipFile: this.form.runEnv === 'java8' ? this.fileList[0].code : this.transBase64(this.code) }, ...this.form }
|
|
||||||
this.$Api.createFunction(funcForm).then((res) => {
|
this.$Api.checkFunctionName(this.form.functionName).then(res => {
|
||||||
if (res) {
|
if (res.data.exist) {
|
||||||
this.$message.success('创建函数成功')
|
this.$message.warning('名称已存在')
|
||||||
this.goDetail(this.form)
|
} else {
|
||||||
this.getList()
|
const funcForm = { code: { zipFile: this.form.runEnv === 'java8' ? this.fileList[0].code : this.transBase64(this.code) }, ...this.form }
|
||||||
|
this.$Api.createFunction(funcForm).then((res) => {
|
||||||
|
if (res) {
|
||||||
|
this.$message.success('创建函数成功')
|
||||||
|
this.goDetail(this.form)
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -55,13 +55,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const UNITS = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
|
|
||||||
const FRACTIONAL = ['', 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y'] // milli micro nano pico femto
|
|
||||||
|
|
||||||
import List from '@/components/list'
|
import List from '@/components/list'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { getDashboardCounts, getDashboardEvents, getDashboardInfo, getUsageStatus, getStorageStatus } from '@/api/one-class-page/virtualMachine'
|
import { getDashboardCounts, getDashboardEvents, getDashboardInfo, getUsageStatus, getStorageStatus } from '@/api/one-class-page/virtualMachine'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
import { parseSi } from '@/utils'
|
||||||
export default {
|
export default {
|
||||||
components: { List },
|
components: { List },
|
||||||
data() {
|
data() {
|
||||||
|
@ -132,8 +130,8 @@ export default {
|
||||||
let memoryCounts = 0
|
let memoryCounts = 0
|
||||||
let cpuCounts = 0
|
let cpuCounts = 0
|
||||||
containers.forEach(e => {
|
containers.forEach(e => {
|
||||||
memoryCounts += this.parseSi(e?.resources?.requests?.memory || '0m', { increment: 1024 })
|
memoryCounts += parseSi(e?.resources?.requests?.memory || '0m', { increment: 1024 })
|
||||||
cpuCounts += this.parseSi(e?.resources?.requests?.cpu || '0m')
|
cpuCounts += parseSi(e?.resources?.requests?.cpu || '0m')
|
||||||
})
|
})
|
||||||
this.memoryUsage += memoryCounts
|
this.memoryUsage += memoryCounts
|
||||||
this.cpuUsage += cpuCounts
|
this.cpuUsage += cpuCounts
|
||||||
|
@ -156,57 +154,6 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
parseSi(inValue, opt) {
|
|
||||||
opt = opt || {}
|
|
||||||
let increment = opt.increment
|
|
||||||
const allowFractional = opt.allowFractional !== false
|
|
||||||
|
|
||||||
if (!inValue || typeof inValue !== 'string' || !inValue.length) {
|
|
||||||
return NaN
|
|
||||||
}
|
|
||||||
|
|
||||||
inValue = inValue.replace(/,/g, '')
|
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-const
|
|
||||||
let [, valStr, unit, incStr] = inValue.match(/^([0-9.-]+)\s*([^0-9.-]?)([^0-9.-]?)/)
|
|
||||||
const val = parseFloat(valStr)
|
|
||||||
|
|
||||||
if (!unit) {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// micro "mu" symbol -> u
|
|
||||||
if (unit.charCodeAt(0) === 181) {
|
|
||||||
unit = 'u'
|
|
||||||
}
|
|
||||||
|
|
||||||
const divide = FRACTIONAL.includes(unit)
|
|
||||||
const multiply = UNITS.includes(unit.toUpperCase())
|
|
||||||
|
|
||||||
if (!increment) {
|
|
||||||
// Automatically handle 1 KB = 1000B, 1 KiB = 1024B if no increment set
|
|
||||||
if ((multiply || divide) && incStr === 'i') {
|
|
||||||
increment = 1024
|
|
||||||
} else {
|
|
||||||
increment = 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (divide && allowFractional) {
|
|
||||||
const exp = FRACTIONAL.indexOf(unit)
|
|
||||||
|
|
||||||
return val / (increment ** exp)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (multiply) {
|
|
||||||
const exp = UNITS.indexOf(unit.toUpperCase())
|
|
||||||
|
|
||||||
return val * (increment ** exp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unrecognized unit character
|
|
||||||
return val
|
|
||||||
},
|
|
||||||
formatDate(t) {
|
formatDate(t) {
|
||||||
return moment(t).local().format('YYYY-MM-DD hh:mm:ss')
|
return moment(t).local().format('YYYY-MM-DD hh:mm:ss')
|
||||||
},
|
},
|
||||||
|
@ -214,7 +161,7 @@ export default {
|
||||||
const cpuGauge = echarts.init(this.$refs.cpuGauge)
|
const cpuGauge = echarts.init(this.$refs.cpuGauge)
|
||||||
cpuGauge.setOption(this.returnGaugeOption((this.cpuUsage / this.cpuTotal).toFixed(4) * 100))
|
cpuGauge.setOption(this.returnGaugeOption((this.cpuUsage / this.cpuTotal).toFixed(4) * 100))
|
||||||
const memoryGauge = echarts.init(this.$refs.memoryGauge)
|
const memoryGauge = echarts.init(this.$refs.memoryGauge)
|
||||||
memoryGauge.setOption(this.returnGaugeOption((parseInt(this.memoryUsage / 1024 / 1024 / 1024) / parseInt(this.memoryTotal / 1024 / 1024)).toFixed(4) * 100))
|
memoryGauge.setOption(this.returnGaugeOption(((parseInt(this.memoryUsage / 1024 / 1024 / 1024) / parseInt(this.memoryTotal / 1024 / 1024)) * 100).toFixed(2)))
|
||||||
const storageGauge = echarts.init(this.$refs.storageGauge)
|
const storageGauge = echarts.init(this.$refs.storageGauge)
|
||||||
storageGauge.setOption(this.returnGaugeOption(((this.storageUsage / 1024 / 1024 / 1024 / 1024).toFixed(2) / (this.storageTotal / 1024 / 1024 / 1024 / 1024).toFixed(2)).toFixed(4) * 100))
|
storageGauge.setOption(this.returnGaugeOption(((this.storageUsage / 1024 / 1024 / 1024 / 1024).toFixed(2) / (this.storageTotal / 1024 / 1024 / 1024 / 1024).toFixed(2)).toFixed(4) * 100))
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<script>
|
<script>
|
||||||
import * as Three from 'three'
|
import * as Three from 'three'
|
||||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||||
import { getEarthRegion } from '@/api/screen -one-class-page/TotalNum'
|
import { getEarthRegion } from '@/api/screen-one-class-page/TotalNum'
|
||||||
import { getEarthDetails } from '@/api/screen -one-class-page/TotalNum'
|
import { getEarthDetails } from '@/api/screen-one-class-page/TotalNum'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="formcontainer">
|
<div class="formcontainer">
|
||||||
<el-form ref="formData" :rules="rules" :model="formData" label-position="top">
|
<el-form ref="formData" :model="formData" label-position="top">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="名称"><el-input
|
<el-form-item label="名称"><el-input
|
||||||
|
@ -78,37 +78,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getImages, getDataVolumeNew, editDataVolume } from '@/api/one-class-page/virtualMachine'
|
import { getImages, getDataVolumeNew, editDataVolume, createDataVolume } from '@/api/one-class-page/virtualMachine'
|
||||||
import { createDataVolume } from '@/api/one-class-page/virtualMachine'
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
volumeData: {
|
volumeData: {},
|
||||||
type: 'cdi.kubevirt.io.datavolume',
|
|
||||||
metadata: {
|
|
||||||
namespace: 'default',
|
|
||||||
annotations: {
|
|
||||||
'field.cattle.io/description': ''
|
|
||||||
// 'harvesterhci.io/imageId': null
|
|
||||||
},
|
|
||||||
labels: {},
|
|
||||||
name: ''
|
|
||||||
},
|
|
||||||
spec: {
|
|
||||||
pvc: {
|
|
||||||
resources: {
|
|
||||||
requests: {
|
|
||||||
storage: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
volumeMode: 'Block',
|
|
||||||
accessModes: ['ReadWriteMany']
|
|
||||||
},
|
|
||||||
source: {
|
|
||||||
blank: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Data: {},
|
Data: {},
|
||||||
tagNum: 0,
|
tagNum: 0,
|
||||||
disableConfig: true,
|
disableConfig: true,
|
||||||
|
@ -198,15 +172,31 @@ export default {
|
||||||
this.$router.push({ path: '/virtual/dataVolume' })
|
this.$router.push({ path: '/virtual/dataVolume' })
|
||||||
},
|
},
|
||||||
create() {
|
create() {
|
||||||
this.volumeData.metadata.annotations['field.cattle.io/description'] = this.formData.description
|
this.volumeData = {
|
||||||
if (this.formData.resourceType === 'VM Image') this.volumeData.metadata.annotations['harvesterhci.io/imageId'] = this.formData.imageId
|
apiVersion: 'v1',
|
||||||
for (let item = 0; item < this.formData.tag.length; item++) {
|
kind: 'PersistentVolumeClaim',
|
||||||
this.volumeData.metadata.labels[this.formData.tag[item].key] = this.formData.tag[item].value
|
metadata: {
|
||||||
|
annotations: {
|
||||||
|
'field.cattle.io/description': this.formData.description || '',
|
||||||
|
'harvesterhci.io/imageId': this.formData.resourceType === 'VM Image' ? this.formData.imageId : undefined
|
||||||
|
},
|
||||||
|
name: this.formData.name || '',
|
||||||
|
namespace: 'default'
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
accessModes: ['ReadWriteMany'],
|
||||||
|
resources: {
|
||||||
|
requests: {
|
||||||
|
storage: this.formData.size + 'Gi'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
storageClassName: this.formData.resourceType === 'VM Image' ? `longhorn-${this.formData.imageId.replace('default/', '')}` : 'longhorn',
|
||||||
|
volumeMode: 'Block',
|
||||||
|
volumeName: ''
|
||||||
|
},
|
||||||
|
type: 'persistentvolumeclaim'
|
||||||
}
|
}
|
||||||
this.volumeData.metadata.name = this.formData.name
|
|
||||||
this.volumeData.spec.pvc.resources.requests.storage = this.formData.size + 'Gi'
|
|
||||||
createDataVolume(this.volumeData).then(res => {
|
createDataVolume(this.volumeData).then(res => {
|
||||||
console.log(res)
|
|
||||||
this.$message.success('创建成功')
|
this.$message.success('创建成功')
|
||||||
this.goBack()
|
this.goBack()
|
||||||
})
|
})
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
getHostYaml,
|
getHostYaml,
|
||||||
getHostNetwork,
|
// getHostNetwork,
|
||||||
putHostYaml,
|
putHostYaml,
|
||||||
putHostNetwork,
|
putHostNetwork,
|
||||||
getNodeNetworks
|
getNodeNetworks
|
||||||
|
@ -139,11 +139,11 @@ export default {
|
||||||
this.formData.customName = res.metadata.annotations['harvesterhci.io/host-custom-name']
|
this.formData.customName = res.metadata.annotations['harvesterhci.io/host-custom-name']
|
||||||
this.yamlData = res
|
this.yamlData = res
|
||||||
})
|
})
|
||||||
getHostNetwork(this.$route.query.name).then(res => {
|
// getHostNetwork(this.$route.query.name).then(res => {
|
||||||
this.formData.type = res.spec.type
|
// this.formData.type = res.spec.type
|
||||||
this.formData.physicalNIC = res.spec.nic
|
// this.formData.physicalNIC = res.spec.nic
|
||||||
this.vlanData = res
|
// this.vlanData = res
|
||||||
})
|
// })
|
||||||
getNodeNetworks().then(res => {
|
getNodeNetworks().then(res => {
|
||||||
this.physicalNICList = res.data[this.$route.query.index].status.physicalNICs
|
this.physicalNICList = res.data[this.$route.query.index].status.physicalNICs
|
||||||
})
|
})
|
||||||
|
|
|
@ -194,15 +194,15 @@ export default {
|
||||||
this.formData.lastUpdateTime = res.data[this.formData.index].status.conditions[0].lastUpdateTime
|
this.formData.lastUpdateTime = res.data[this.formData.index].status.conditions[0].lastUpdateTime
|
||||||
this.formData.uuid = res.data[this.formData.index].status.nodeInfo.systemUUID
|
this.formData.uuid = res.data[this.formData.index].status.nodeInfo.systemUUID
|
||||||
|
|
||||||
this.formData.cpuUsed = parseFloat((parseInt(usage.usage.cpu) / 1000000000).toFixed(2))
|
this.formData.cpuUsed = this.$route.query.cpuUsed
|
||||||
this.formData.cpuAll = parseInt(res.data[this.formData.index].status.capacity.cpu)
|
this.formData.cpuAll = this.$route.query.cpuAll
|
||||||
this.formData.cpuUsePercentage = parseFloat((this.formData.cpuUsed / this.formData.cpuAll).toFixed(2)) * 100
|
this.formData.cpuUsePercentage = this.$route.query.cpuUsePercentage
|
||||||
this.formData.memoryUsed = parseFloat((parseInt(usage.usage.memory) / 1024 / 1024).toFixed(2))
|
this.formData.memoryUsed = this.$route.query.memoryUsed
|
||||||
this.formData.memoryAll = parseFloat((parseFloat(res.data[this.formData.index].status.capacity.memory) / 1024 / 1024).toFixed(2))
|
this.formData.memoryAll = this.$route.query.memoryAll
|
||||||
this.formData.memoryUsePercentage = parseFloat((this.formData.memoryUsed / this.formData.memoryAll).toFixed(2)) * 100
|
this.formData.memoryUsePercentage = this.$route.query.memoryUsePercentage
|
||||||
this.formData.storageUsed = parseFloat((parseFloat(res.data[this.formData.index].status.capacity['ephemeral-storage']) / 1024 / 1024 / 1024 - parseFloat(res.data[this.formData.index].status.allocatable['ephemeral-storage']) / 1024 / 1024 / 1024 / 1024).toFixed(2))
|
this.formData.storageUsed = this.$route.query.storageUsed
|
||||||
this.formData.storageAll = parseFloat((parseFloat(res.data[this.formData.index].status.capacity['ephemeral-storage']) / 1024 / 1024 / 1024).toFixed(2))
|
this.formData.storageAll = this.$route.query.storageAll
|
||||||
this.formData.storageUsePercentage = parseFloat((this.formData.storageUsed / this.formData.storageAll).toFixed(2)) * 100
|
this.formData.storageUsePercentage = this.$route.query.storageUsePercentage
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
func-name="getImagesList"
|
func-name="getImagesList"
|
||||||
:cluster-name="clusterName"
|
:cluster-name="clusterName"
|
||||||
:pagination="true"
|
:pagination="false"
|
||||||
tooltip-effect="dark"
|
tooltip-effect="dark"
|
||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
@ -78,7 +78,6 @@ export default {
|
||||||
<el-dropdown-menu slot='dropdown'>
|
<el-dropdown-menu slot='dropdown'>
|
||||||
<span onClick={() => this.clickOption(row, 1)}> <el-dropdown-item><i class='el-icon-edit'></i> 编辑配置 </el-dropdown-item> </span>
|
<span onClick={() => this.clickOption(row, 1)}> <el-dropdown-item><i class='el-icon-edit'></i> 编辑配置 </el-dropdown-item> </span>
|
||||||
<span onClick={() => this.clickOption(row, 2)}> <el-dropdown-item><i class='el-icon-tickets'></i> 克隆 </el-dropdown-item> </span>
|
<span onClick={() => this.clickOption(row, 2)}> <el-dropdown-item><i class='el-icon-tickets'></i> 克隆 </el-dropdown-item> </span>
|
||||||
<span onClick={() => this.clickOption(row, 3)}> <el-dropdown-item><i class='el-icon-document'></i> 创建虚拟机 </el-dropdown-item> </span>
|
|
||||||
<span onClick={() => this.clickOption(row, 4)}> <el-dropdown-item><i class='el-icon-download'></i> 下载YAML </el-dropdown-item> </span>
|
<span onClick={() => this.clickOption(row, 4)}> <el-dropdown-item><i class='el-icon-download'></i> 下载YAML </el-dropdown-item> </span>
|
||||||
<span onClick={() => this.clickOption(row, 5)}> <el-dropdown-item divided><i class='el-icon-delete'></i> 删除 </el-dropdown-item> </span>
|
<span onClick={() => this.clickOption(row, 5)}> <el-dropdown-item divided><i class='el-icon-delete'></i> 删除 </el-dropdown-item> </span>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
|
@ -132,7 +131,7 @@ export default {
|
||||||
this.$router.push({ path: `virtual-machine/create`, query: row })
|
this.$router.push({ path: `virtual-machine/create`, query: row })
|
||||||
break
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.downloadHostYaml(row.name)
|
this.downloadHostYaml(row)
|
||||||
break
|
break
|
||||||
case 5:
|
case 5:
|
||||||
this.deleteDialogVisible = true
|
this.deleteDialogVisible = true
|
||||||
|
@ -151,8 +150,8 @@ export default {
|
||||||
viewVMDetail(row) {
|
viewVMDetail(row) {
|
||||||
this.$router.push({ path: `virtual-machine/detail`, query: row })
|
this.$router.push({ path: `virtual-machine/detail`, query: row })
|
||||||
},
|
},
|
||||||
downloadHostYaml(name) {
|
downloadHostYaml(row) {
|
||||||
getImagesYaml(name).then(res => {
|
getImagesYaml(row.name).then(res => {
|
||||||
var data = JSON.stringify(res)
|
var data = JSON.stringify(res)
|
||||||
// encodeURIComponent解决中文乱码
|
// encodeURIComponent解决中文乱码
|
||||||
const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(data)
|
const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(data)
|
||||||
|
@ -160,7 +159,7 @@ export default {
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = uri
|
link.href = uri
|
||||||
// 对下载的文件命名
|
// 对下载的文件命名
|
||||||
link.download = name + '.json'
|
link.download = row.displayName + '.json'
|
||||||
document.body.appendChild(link)
|
document.body.appendChild(link)
|
||||||
link.click()
|
link.click()
|
||||||
document.body.removeChild(link)
|
document.body.removeChild(link)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="formcontainer">
|
<div class="formcontainer">
|
||||||
<el-form ref="formData" :rules="rules" :model="formData" label-position="top">
|
<el-form ref="formData" :model="formData" label-position="top">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="名称"><el-input
|
<el-form-item label="名称"><el-input
|
||||||
|
@ -22,26 +22,24 @@
|
||||||
<el-tab-pane label="基本信息">
|
<el-tab-pane label="基本信息">
|
||||||
<h4>基本信息</h4>
|
<h4>基本信息</h4>
|
||||||
<el-form-item label="镜像地址">
|
<el-form-item label="镜像地址">
|
||||||
<el-select v-model="formData.resourceType" :disabled="!clone">
|
<el-input
|
||||||
<el-option
|
v-model="formData.url"
|
||||||
v-for="item in options1"
|
:hide-required-asterisk="true"
|
||||||
:key="item.value"
|
:disabled="!clone"
|
||||||
:label="item.label"
|
placeholder="镜像地址"
|
||||||
:value="item.value"
|
/>
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="标签">
|
<el-tab-pane label="标签">
|
||||||
<h4>标签</h4>
|
<h4>标签</h4>
|
||||||
<div v-for="(item, index) in formData.tag" :key="item.id">
|
<div v-for="(item, i) in formData.tag" :key="item.id">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-row v-if="index=='0'" :gutter="20"><el-col :span="6"><h5>键</h5></el-col><el-col :span="6"><h5>值</h5></el-col></el-row>
|
<el-row v-if="i=='0'" :gutter="20"><el-col :span="6"><h5>键</h5></el-col><el-col :span="6"><h5>值</h5></el-col></el-row>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="6"><el-input v-model="item.key" placeholder="例如:test" /></el-col>
|
<el-col :span="6"><el-input v-model="item.key" placeholder="例如:test" /></el-col>
|
||||||
<el-col :span="6"> <el-input v-model="item.value" placeholder="例如:test" /></el-col>
|
<el-col :span="6"> <el-input v-model="item.value" placeholder="例如:test" /></el-col>
|
||||||
<el-col :span="5"><el-button type="danger" icon="el-icon-delete" @click="removeTag(index)" /></el-col>
|
<el-col v-if="!isDisabled" :span="5"><el-button type="danger" icon="el-icon-delete" @click="removeTag(i)" /></el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,25 +52,28 @@
|
||||||
<el-row type="flex" justify="end">
|
<el-row type="flex" justify="end">
|
||||||
<el-col :span="2.5">
|
<el-col :span="2.5">
|
||||||
<el-button v-if="!isDisabled" type="info" @click="goBack">取消</el-button>
|
<el-button v-if="!isDisabled" type="info" @click="goBack">取消</el-button>
|
||||||
<el-button v-if="!isDisabled" type="primary">创建</el-button>
|
<el-button v-if="clone" type="primary" @click="create">创建</el-button>
|
||||||
|
<el-button v-if="!clone && !isDisabled" type="primary" @click="edit">保存</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { getImages, editImage, createImages } from '@/api/one-class-page/virtualMachine'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tagNum: 0,
|
tagNum: 0,
|
||||||
|
index: '',
|
||||||
disableConfig: true,
|
disableConfig: true,
|
||||||
clone: false,
|
clone: false,
|
||||||
|
currentData: '',
|
||||||
formData: {
|
formData: {
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
size: '',
|
size: '',
|
||||||
resourceType: 'https://github.com/rancher/k3os/releases/download/v0.11.1/k3os-amd64.iso',
|
|
||||||
image: '',
|
image: '',
|
||||||
tag: []
|
tag: []
|
||||||
}
|
}
|
||||||
|
@ -83,6 +84,9 @@ export default {
|
||||||
return this.disableConfig && !this.clone
|
return this.disableConfig && !this.clone
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.index = this.$route.query.index
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getFormData()
|
this.getFormData()
|
||||||
if (this.$route.query.disableConfig != null && typeof (this.$route.query.disableConfig) !== 'undefined') {
|
if (this.$route.query.disableConfig != null && typeof (this.$route.query.disableConfig) !== 'undefined') {
|
||||||
|
@ -94,10 +98,22 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getFormData() {
|
getFormData() {
|
||||||
this.formData.name = this.$route.query.name
|
getImages().then(res => {
|
||||||
this.formData.size = this.$route.query.size.slice(0, -2)
|
var data = res.data[this.index]
|
||||||
// this.formData.description = this.$route.query.description,
|
this.currentData = data
|
||||||
// this.formData.resourceType = this.$route.query.resourceType
|
this.formData = {
|
||||||
|
name: this.$route.query.displayName,
|
||||||
|
description: data.metadata.annotations['field.cattle.io/description'],
|
||||||
|
size: Number((data.status.size / 1024 / 1024).toString().match(/^\d+(?:\.\d{0,2})?/)) + 'MB',
|
||||||
|
url: data.spec.url,
|
||||||
|
image: data.spec.url
|
||||||
|
}
|
||||||
|
const arry = []
|
||||||
|
for (const i in data.metadata.labels) {
|
||||||
|
arry.push({ 'key': i, 'value': data.metadata.labels[i] })
|
||||||
|
}
|
||||||
|
this.formData.tag = arry
|
||||||
|
})
|
||||||
},
|
},
|
||||||
addTag() {
|
addTag() {
|
||||||
this.formData.tag.push(
|
this.formData.tag.push(
|
||||||
|
@ -108,11 +124,53 @@ export default {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
create() {
|
||||||
|
this.imagesData = {
|
||||||
|
'apiVersion': this.currentData.apiVersion,
|
||||||
|
'kind': this.currentData.kind,
|
||||||
|
'metadata': {
|
||||||
|
annotations: {
|
||||||
|
'field.cattle.io/description': this.formData.description
|
||||||
|
},
|
||||||
|
finalizers: this.currentData.metadata.finalizers,
|
||||||
|
generateName: 'image-',
|
||||||
|
labels: {},
|
||||||
|
name: '',
|
||||||
|
namespace: 'default'
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'displayName': this.formData.name,
|
||||||
|
'url': this.formData.url,
|
||||||
|
checksum: '',
|
||||||
|
pvcName: '',
|
||||||
|
pvcNamespace: '',
|
||||||
|
sourceType: 'download'
|
||||||
|
},
|
||||||
|
'type': this.currentData.type
|
||||||
|
}
|
||||||
|
for (let item = 0; item < this.formData.tag.length; item++) {
|
||||||
|
this.imagesData.metadata.labels[this.formData.tag[item].key] = this.formData.tag[item].value
|
||||||
|
}
|
||||||
|
createImages(this.imagesData).then(res => {
|
||||||
|
this.$message.success('创建成功')
|
||||||
|
this.goBack()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
edit() {
|
||||||
|
this.currentData.metadata.annotations['field.cattle.io/description'] = this.formData.description
|
||||||
|
for (let item = 0; item < this.formData.tag.length; item++) {
|
||||||
|
this.currentData.metadata.labels[this.formData.tag[item].key] = this.formData.tag[item].value
|
||||||
|
}
|
||||||
|
editImage(this.$route.query.name, this.currentData).then(res => {
|
||||||
|
this.$message.success('修改成功')
|
||||||
|
this.goBack()
|
||||||
|
})
|
||||||
|
},
|
||||||
removeTag(index) {
|
removeTag(index) {
|
||||||
this.formData.tag.splice(index, 1)
|
this.formData.tag.splice(index, 1)
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
this.$router.push({ path: '/virtual/images.vue' })
|
this.$router.push({ path: '/virtual/images' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { FormData } from '@/components/FormData'
|
import { FormData } from '@/components/FormData'
|
||||||
|
import { getImages } from '@/api/one-class-page/virtualMachine'
|
||||||
export default {
|
export default {
|
||||||
components: { FormData },
|
components: { FormData },
|
||||||
data() {
|
data() {
|
||||||
|
@ -23,7 +24,7 @@ export default {
|
||||||
formData1: {
|
formData1: {
|
||||||
description: ' ',
|
description: ' ',
|
||||||
size: this.$route.query.size,
|
size: this.$route.query.size,
|
||||||
resourceType: 'https://github.com/rancher/k3os/releases/download/v0.11.1/k3os-amd64.iso'
|
resourceType: ''
|
||||||
},
|
},
|
||||||
dataMap1: {
|
dataMap1: {
|
||||||
description: '描述',
|
description: '描述',
|
||||||
|
@ -64,7 +65,16 @@ export default {
|
||||||
this.getFormData()
|
this.getFormData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getFormData() {}
|
getFormData() {
|
||||||
|
getImages().then(res => {
|
||||||
|
var data = res.data[this.index]
|
||||||
|
this.formData1 = {
|
||||||
|
description: data.metadata.annotations['field.cattle.io/description'],
|
||||||
|
size: Number((data.status.size / 1024 / 1024).toString().match(/^\d+(?:\.\d{0,2})?/)) + 'MB',
|
||||||
|
resourceType: data.spec.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -33,14 +33,14 @@
|
||||||
width="30%"
|
width="30%"
|
||||||
>
|
>
|
||||||
<p>您试图删除 虚拟机 {{ deleteName }} .</p>
|
<p>您试图删除 虚拟机 {{ deleteName }} .</p>
|
||||||
<p>Select the volume you want to delete:</p>
|
<p>选择您需要删除的卷:</p>
|
||||||
<el-checkbox-group v-model="selectDeleteVolumeList">
|
<el-checkbox-group v-model="selectDeleteVolumeList">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-for="data in deleteVolumeList"
|
v-for="data in deleteVolumeList"
|
||||||
:key="data.name"
|
:key="data"
|
||||||
:label="data.name"
|
:label="data"
|
||||||
>
|
>
|
||||||
{{ data.name }}
|
{{ data }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
|
|
||||||
|
@ -103,6 +103,8 @@ export default {
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
if (row.state === 'Running') {
|
if (row.state === 'Running') {
|
||||||
return <el-tag disable-transitions type='success'>{row.state}</el-tag>
|
return <el-tag disable-transitions type='success'>{row.state}</el-tag>
|
||||||
|
} else if (row.state === 'Stopped') {
|
||||||
|
return <el-tag disable-transitions type='info'>Off</el-tag>
|
||||||
} else {
|
} else {
|
||||||
return <span>
|
return <span>
|
||||||
<el-tag disable-transitions>{row.state}</el-tag>
|
<el-tag disable-transitions>{row.state}</el-tag>
|
||||||
|
@ -169,10 +171,9 @@ export default {
|
||||||
// },
|
// },
|
||||||
deleteVirtualMachine() {
|
deleteVirtualMachine() {
|
||||||
this.deleteDialogVisible = false
|
this.deleteDialogVisible = false
|
||||||
console.log(this.selectDeleteVolumeList)
|
|
||||||
deleteVirtualMachine(this.deleteName, this.selectDeleteVolumeList).then(res => {
|
deleteVirtualMachine(this.deleteName, this.selectDeleteVolumeList).then(res => {
|
||||||
alert('删除成功')
|
this.$message.success('删除成功')
|
||||||
location.reload()
|
this.$refs.multipleTable.getList()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
createVirtualMachine() {
|
createVirtualMachine() {
|
||||||
|
@ -219,9 +220,9 @@ export default {
|
||||||
getVirtualMachines().then(res => {
|
getVirtualMachines().then(res => {
|
||||||
var data = res.data[row.index]
|
var data = res.data[row.index]
|
||||||
this.deleteVolumeList = []
|
this.deleteVolumeList = []
|
||||||
for (let i = 0; i < data.spec.template.spec.volumes.length; i++) {
|
for (let i = 0; i < data.status?.volumeSnapshotStatuses?.length; i++) {
|
||||||
if (data.spec.template.spec.volumes[i].dataVolume != null) {
|
if (data.status.volumeSnapshotStatuses[i].name !== 'cloudinitdisk') {
|
||||||
this.deleteVolumeList.push(data.spec.template.spec.volumes[i])
|
this.deleteVolumeList.push(data.status.volumeSnapshotStatuses[i].name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.deleteName = row.name
|
this.deleteName = row.name
|
||||||
|
|
|
@ -137,7 +137,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getImages, postSSHKey, getDataVolume, getSSHKey } from '@/api/one-class-page/virtualMachine'
|
import { getImages, postSSHKey, getDataVolumeNew, getSSHKey } from '@/api/one-class-page/virtualMachine'
|
||||||
import ConfigVolume from './virtualMachineConfig/configVolume'
|
import ConfigVolume from './virtualMachineConfig/configVolume'
|
||||||
import ConfigImage from './virtualMachineConfig/configImage'
|
import ConfigImage from './virtualMachineConfig/configImage'
|
||||||
import ConfigExistedVolume from './virtualMachineConfig/configExistedVolume'
|
import ConfigExistedVolume from './virtualMachineConfig/configExistedVolume'
|
||||||
|
@ -347,7 +347,7 @@ export default {
|
||||||
this.getSSHKeys()
|
this.getSSHKeys()
|
||||||
getImages().then(res => {
|
getImages().then(res => {
|
||||||
this.imageList = res.data
|
this.imageList = res.data
|
||||||
getDataVolume().then(res => {
|
getDataVolumeNew().then(res => {
|
||||||
this.volumeList = res.data
|
this.volumeList = res.data
|
||||||
this.show = true
|
this.show = true
|
||||||
})
|
})
|
||||||
|
@ -363,15 +363,14 @@ export default {
|
||||||
getImages().then(res => {
|
getImages().then(res => {
|
||||||
images = res.data
|
images = res.data
|
||||||
this.imageList = res.data
|
this.imageList = res.data
|
||||||
getDataVolume().then(res => {
|
getDataVolumeNew().then(res => {
|
||||||
dataVolumeData = res.data
|
dataVolumeData = res.data
|
||||||
this.volumeList = dataVolumeData
|
this.volumeList = dataVolumeData
|
||||||
// getVirtualMachines().then(res => {
|
// getVirtualMachines().then(res => {
|
||||||
var data = this.instanceData // res.data[this.$route.query.index]
|
var data = this.instanceData // res.data[this.$route.query.index]
|
||||||
var dataImageName = null
|
var dataImageName = null
|
||||||
for (let item = 0; item < data.spec.template.spec.volumes.length; item++) {
|
data.spec.template.spec.volumes.forEach(item => {
|
||||||
var dataVolumeTemplate = data.spec.template.spec.volumes[item]
|
var volumeName = item.name
|
||||||
var volumeName = dataVolumeTemplate.name
|
|
||||||
dataImageName = null
|
dataImageName = null
|
||||||
var bus = null
|
var bus = null
|
||||||
var bootOrder = null
|
var bootOrder = null
|
||||||
|
@ -380,16 +379,14 @@ export default {
|
||||||
var componentType = null
|
var componentType = null
|
||||||
var dataVolumeName = null
|
var dataVolumeName = null
|
||||||
var imageId = null
|
var imageId = null
|
||||||
if (dataVolumeTemplate.dataVolume != null) {
|
if (item.dataVolume != null) {
|
||||||
dataVolumeName = dataVolumeTemplate.dataVolume.name
|
dataVolumeName = item.dataVolume.name
|
||||||
} else if (dataVolumeTemplate.containerDisk != null) {
|
} else if (item.containerDisk != null) {
|
||||||
dataVolumeName = dataVolumeTemplate.containerDisk.image
|
dataVolumeName = item.containerDisk.image
|
||||||
componentType = 'Container'
|
componentType = 'Container'
|
||||||
} else if (dataVolumeTemplate.cloudInitNoCloud != null) {
|
} else if (item.cloudInitNoCloud != null) {
|
||||||
this.formData.userData = dataVolumeTemplate.cloudInitNoCloud.userData
|
this.formData.userData = item.cloudInitNoCloud.userData
|
||||||
continue
|
return
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
for (let item1 = 0; item1 < dataVolumeData.length; item1++) {
|
for (let item1 = 0; item1 < dataVolumeData.length; item1++) {
|
||||||
if (dataVolumeName === dataVolumeData[item1].metadata.fields[0]) {
|
if (dataVolumeName === dataVolumeData[item1].metadata.fields[0]) {
|
||||||
|
@ -412,7 +409,7 @@ export default {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let item1 = 0; item1 < data.spec.dataVolumeTemplates.length; item1++) {
|
for (let item1 = 0; item1 < data.spec?.dataVolumeTemplates?.length; item1++) {
|
||||||
if (data.spec.dataVolumeTemplates[item1].metadata.name !== dataVolumeName) {
|
if (data.spec.dataVolumeTemplates[item1].metadata.name !== dataVolumeName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -436,7 +433,7 @@ export default {
|
||||||
// Name,type,Image,Size,Bus,BootOrder,docker,isCreate, disableConfig, volumeList, imageId
|
// Name,type,Image,Size,Bus,BootOrder,docker,isCreate, disableConfig, volumeList, imageId
|
||||||
this.childLists.push([volumeName, type, dataImageName, size, bus, bootOrder, dataVolumeName, null, true, this.volumeList, imageId])
|
this.childLists.push([volumeName, type, dataImageName, size, bus, bootOrder, dataVolumeName, null, true, this.volumeList, imageId])
|
||||||
this.allComponents.push(componentType)
|
this.allComponents.push(componentType)
|
||||||
}
|
})
|
||||||
this.formData.name = data.metadata.name
|
this.formData.name = data.metadata.name
|
||||||
this.formData.description = data.metadata.annotations['field.cattle.io/description']
|
this.formData.description = data.metadata.annotations['field.cattle.io/description']
|
||||||
this.formData.customName = data.metadata.annotations['harvesterhci.io/host-custom-name']
|
this.formData.customName = data.metadata.annotations['harvesterhci.io/host-custom-name']
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<h4>网络</h4>
|
<h4>网络</h4>
|
||||||
<VirtualMachineDetailCard v-for="(item, ind) in allNetworkCard" :key="ind" card-name="网络" :data-map="dataMap5" :form-data="item" />
|
<VirtualMachineDetailCard v-for="(item, ind) in allNetworkCard" :key="ind" card-name="网络" :data-map="dataMap5" :form-data="item" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane key="4" label="SSH 秘钥">
|
<el-tab-pane key="4" label="SSH 密钥">
|
||||||
<h4>SSH Keys</h4>
|
<h4>SSH Keys</h4>
|
||||||
<div v-for="(item,index) in sshkeyLists" :key="index">
|
<div v-for="(item,index) in sshkeyLists" :key="index">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { FormData } from '@/components/FormData'
|
import { FormData } from '@/components/FormData'
|
||||||
import List from '@/components/list'
|
import List from '@/components/list'
|
||||||
import { getVirtualMachines, getImages, getDataVolume, getSSHKey } from '@/api/one-class-page/virtualMachine'
|
import { getVirtualMachines, getImages, getDataVolumeNew, getSSHKey, getVirtualMachinesInstances } from '@/api/one-class-page/virtualMachine'
|
||||||
import VirtualMachineDetailCard from './virtualMachineConfig/virtualMachineDetailCard'
|
import VirtualMachineDetailCard from './virtualMachineConfig/virtualMachineDetailCard'
|
||||||
export default {
|
export default {
|
||||||
name: 'VirtualMachineDetail',
|
name: 'VirtualMachineDetail',
|
||||||
|
@ -125,8 +125,8 @@ export default {
|
||||||
dataMap: {
|
dataMap: {
|
||||||
name: '名称',
|
name: '名称',
|
||||||
image: '镜像',
|
image: '镜像',
|
||||||
hostname: '主机名',
|
node: '节点名称',
|
||||||
node: '节点',
|
hostname: '主机',
|
||||||
IPAddress: 'IP地址',
|
IPAddress: 'IP地址',
|
||||||
created: '创建时间'
|
created: '创建时间'
|
||||||
},
|
},
|
||||||
|
@ -175,7 +175,7 @@ export default {
|
||||||
dataMap8: {
|
dataMap8: {
|
||||||
Name: '名称',
|
Name: '名称',
|
||||||
Type: '类型',
|
Type: '类型',
|
||||||
Volume: '卷名称',
|
// Volume: '卷名称',
|
||||||
Size: '大小',
|
Size: '大小',
|
||||||
Bus: '总线',
|
Bus: '总线',
|
||||||
BootOrder: '驱动顺序'
|
BootOrder: '驱动顺序'
|
||||||
|
@ -207,167 +207,169 @@ export default {
|
||||||
// TODO Basics 面板的Image, Node IP Address 字段都未知
|
// TODO Basics 面板的Image, Node IP Address 字段都未知
|
||||||
var images = null
|
var images = null
|
||||||
var dataVolumeData = null
|
var dataVolumeData = null
|
||||||
getImages().then(res => {
|
Promise.all([
|
||||||
images = res.data
|
getImages(),
|
||||||
getDataVolume().then(res => {
|
getDataVolumeNew(),
|
||||||
dataVolumeData = res.data
|
getVirtualMachines(),
|
||||||
getVirtualMachines().then(res => {
|
getVirtualMachinesInstances()]).then(res => {
|
||||||
var data = res.data[this.$route.query.index]
|
images = res[0].data
|
||||||
for (let item = 0; item < data.spec.template.spec.volumes.length; item++) {
|
dataVolumeData = res[1].data
|
||||||
var dataVolumeTemplate = data.spec.template.spec.volumes[item]
|
var data = res[2].data[this.index]
|
||||||
var volumeName = dataVolumeTemplate.name
|
var currentVm = res[3].data.filter(n => n.id === data.id)?.[0]
|
||||||
var dataImageName = null
|
data.spec?.template?.spec?.volumes?.forEach(item => {
|
||||||
var bus = null
|
var volumeName = item.name
|
||||||
var bootOrder = null
|
var dataImageName = null
|
||||||
var type = null
|
var bus = null
|
||||||
var size = null
|
var bootOrder = null
|
||||||
var componentType = null
|
var type = null
|
||||||
var dataVolumeName = null
|
var size = null
|
||||||
if (dataVolumeTemplate.dataVolume != null) {
|
var componentType = null
|
||||||
dataVolumeName = dataVolumeTemplate.dataVolume.name
|
var dataVolumeName = null
|
||||||
} else if (dataVolumeTemplate.containerDisk != null) {
|
if (item.dataVolume != null) {
|
||||||
dataVolumeName = dataVolumeTemplate.containerDisk.image
|
dataVolumeName = item.dataVolume.name
|
||||||
componentType = '容器镜像'
|
} else if (item.containerDisk != null) {
|
||||||
} else if (dataVolumeTemplate.cloudInitNoCloud != null) {
|
dataVolumeName = item.containerDisk.image
|
||||||
this.formData.userData = dataVolumeTemplate.cloudInitNoCloud.userData
|
componentType = '容器镜像'
|
||||||
continue
|
} else if (item.cloudInitNoCloud != null) {
|
||||||
} else {
|
this.formData.userData = item.cloudInitNoCloud.userData
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
for (let item1 = 0; item1 < dataVolumeData.length; item1++) {
|
for (let item1 = 0; item1 < dataVolumeData.length; item1++) {
|
||||||
if (dataVolumeName === dataVolumeData[item1].metadata.fields[0]) {
|
if (dataVolumeName === dataVolumeData[item1].metadata.fields[0]) {
|
||||||
size = dataVolumeData[item1].spec.pvc.resources.requests.storage
|
size = dataVolumeData[item1].spec.pvc.resources.requests.storage
|
||||||
size = size.replace('Gi', '')
|
size = size.replace('Gi', '')
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let item1 = 0; item1 < data.spec.template.spec.domain.devices.disks.length; item1++) {
|
|
||||||
var disk = data.spec.template.spec.domain.devices.disks[item1]
|
|
||||||
if (volumeName === disk.name) {
|
|
||||||
if (disk.cdrom != null && typeof (disk.cdrom) !== 'undefined') {
|
|
||||||
type = 'cd-rom'
|
|
||||||
bus = disk.cdrom.bus
|
|
||||||
} else {
|
|
||||||
type = 'disk'
|
|
||||||
bus = disk.disk.bus
|
|
||||||
}
|
|
||||||
bootOrder = disk.bootOrder
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let item1 = 0; item1 < data.spec.dataVolumeTemplates.length; item1++) {
|
|
||||||
if (data.spec.dataVolumeTemplates[item1].metadata.name !== dataVolumeName) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (data.spec.dataVolumeTemplates[item1].metadata.annotations != null && typeof (data.spec.dataVolumeTemplates[item1].metadata.annotations) !== 'undefined') {
|
|
||||||
var imageId = data.spec.dataVolumeTemplates[item1].metadata.annotations['harvesterhci.io/imageId']
|
|
||||||
for (let item2 = 0; item2 < images.length; item2++) {
|
|
||||||
if (imageId === images[item2].id) {
|
|
||||||
dataImageName = images[item1].spec.displayName
|
|
||||||
if (item1 === 0) {
|
|
||||||
this.formData.image = dataImageName
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
componentType = 'VM镜像'
|
|
||||||
} else {
|
|
||||||
componentType = '卷'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var formData2 = {
|
|
||||||
Name: volumeName,
|
|
||||||
Type: type,
|
|
||||||
Image: dataImageName,
|
|
||||||
Size: size,
|
|
||||||
Bus: bus,
|
|
||||||
BootOrder: bootOrder,
|
|
||||||
dockerMirror: dataVolumeName,
|
|
||||||
Volume: dataVolumeName
|
|
||||||
}
|
|
||||||
var itemObjct = null
|
|
||||||
if (componentType === 'VM镜像') {
|
|
||||||
itemObjct = {
|
|
||||||
formData: formData2,
|
|
||||||
name: componentType,
|
|
||||||
dataMap: this.dataMap3
|
|
||||||
}
|
|
||||||
} else if (componentType === '卷') {
|
|
||||||
itemObjct = {
|
|
||||||
formData: formData2,
|
|
||||||
name: componentType,
|
|
||||||
dataMap: this.dataMap4
|
|
||||||
}
|
|
||||||
} else if (componentType === '容器镜像') {
|
|
||||||
itemObjct = {
|
|
||||||
formData: formData2,
|
|
||||||
name: componentType,
|
|
||||||
dataMap: this.dataMap7
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
itemObjct = {
|
|
||||||
formData: formData2,
|
|
||||||
name: '现存卷',
|
|
||||||
dataMap: this.dataMap8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.allDetailCard.push(itemObjct)
|
|
||||||
}
|
}
|
||||||
this.allNetworkCard = this.getNetworkRows(data.spec)
|
}
|
||||||
|
for (let item1 = 0; item1 < data.spec.template.spec.domain.devices.disks.length; item1++) {
|
||||||
|
var disk = data.spec.template.spec.domain.devices.disks[item1]
|
||||||
|
if (volumeName === disk.name) {
|
||||||
|
if (disk.cdrom != null && typeof (disk.cdrom) !== 'undefined') {
|
||||||
|
type = 'cd-rom'
|
||||||
|
bus = disk.cdrom.bus
|
||||||
|
} else {
|
||||||
|
type = 'disk'
|
||||||
|
bus = disk.disk.bus
|
||||||
|
}
|
||||||
|
bootOrder = disk.bootOrder
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let item1 = 0; item1 < data.spec?.dataVolumeTemplates?.length; item1++) {
|
||||||
|
if (data.spec.dataVolumeTemplates[item1].metadata.name !== dataVolumeName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (data.spec.dataVolumeTemplates[item1].metadata.annotations != null && typeof (data.spec.dataVolumeTemplates[item1].metadata.annotations) !== 'undefined') {
|
||||||
|
var imageId = data.spec.dataVolumeTemplates[item1].metadata.annotations['harvesterhci.io/imageId']
|
||||||
|
for (let item2 = 0; item2 < images.length; item2++) {
|
||||||
|
if (imageId === images[item2].id) {
|
||||||
|
dataImageName = images[item1].spec.displayName
|
||||||
|
if (item1 === 0) {
|
||||||
|
this.formData.image = dataImageName
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentType = 'VM镜像'
|
||||||
|
} else {
|
||||||
|
componentType = '卷'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var formData2 = {
|
||||||
|
Name: volumeName,
|
||||||
|
Type: type,
|
||||||
|
Image: dataImageName,
|
||||||
|
Size: size,
|
||||||
|
Bus: bus,
|
||||||
|
BootOrder: bootOrder,
|
||||||
|
dockerMirror: dataVolumeName,
|
||||||
|
Volume: dataVolumeName
|
||||||
|
}
|
||||||
|
var itemObjct = null
|
||||||
|
if (componentType === 'VM镜像') {
|
||||||
|
itemObjct = {
|
||||||
|
formData: formData2,
|
||||||
|
name: componentType,
|
||||||
|
dataMap: this.dataMap3
|
||||||
|
}
|
||||||
|
} else if (componentType === '卷') {
|
||||||
|
itemObjct = {
|
||||||
|
formData: formData2,
|
||||||
|
name: componentType,
|
||||||
|
dataMap: this.dataMap4
|
||||||
|
}
|
||||||
|
} else if (componentType === '容器镜像') {
|
||||||
|
itemObjct = {
|
||||||
|
formData: formData2,
|
||||||
|
name: componentType,
|
||||||
|
dataMap: this.dataMap7
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemObjct = {
|
||||||
|
formData: formData2,
|
||||||
|
name: '现存卷',
|
||||||
|
dataMap: this.dataMap8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.allDetailCard.push(itemObjct)
|
||||||
|
})
|
||||||
|
this.allNetworkCard = this.getNetworkRows(data.spec)
|
||||||
|
|
||||||
this.formData.name = data.metadata.name
|
this.formData.name = data.metadata.name
|
||||||
this.formData.description = data.metadata.annotations['field.cattle.io/description']
|
this.formData.description = data.metadata.annotations['field.cattle.io/description']
|
||||||
this.formData.customName = data.metadata.annotations['harvesterhci.io/host-custom-name']
|
this.formData.customName = data.metadata.annotations['harvesterhci.io/host-custom-name']
|
||||||
this.formData.machineType = data.spec.template.spec.domain.machine.type
|
this.formData.machineType = data.spec.template.spec.domain.machine.type
|
||||||
this.formData.cpu = data.spec.template.spec.domain.cpu.cores
|
this.formData.cpu = data.spec.template.spec.domain.cpu.cores
|
||||||
this.formData.memory = data.spec.template.spec.domain.resources.requests.memory
|
this.formData.memory = data.spec.template.spec.domain.resources.requests.memory
|
||||||
this.formData.memory = this.formData.memory.replace('Gi', '')
|
this.formData.memory = this.formData.memory.replace('Gi', '')
|
||||||
this.formData.hostname = data.spec.template.spec.hostname
|
this.formData.hostname = currentVm?.metadata.fields[4]
|
||||||
data = res.data[this.index]
|
this.formData.IPAddress = currentVm?.metadata.fields[3]
|
||||||
this.formData.name = data.metadata.fields[0]
|
this.formData.node = currentVm?.metadata.fields[0]
|
||||||
this.formData.created = data.metadata.creationTimestamp
|
this.formData.KernelRelease = currentVm?.status?.guestOSInfo?.kernelRelease
|
||||||
this.formData.MachineType = data.spec.template.spec.domain.machine.type
|
this.formData.OperatingSystem = currentVm?.status?.guestOSInfo?.prettyName
|
||||||
var disks = data.spec.template.spec.domain.devices.disks
|
// data = res.data[this.index]
|
||||||
var disksarr = []
|
this.formData.name = data.metadata.fields[0]
|
||||||
var cdroms = []
|
this.formData.created = data.metadata.creationTimestamp
|
||||||
this.formData.CDROMs = ''
|
this.formData.MachineType = data.spec.template.spec.domain.machine.type
|
||||||
var maxIndex = 0
|
var disks = data.spec.template.spec.domain.devices.disks
|
||||||
for (let item = 0; item < disks.length; item++) {
|
var disksarr = []
|
||||||
if (disks[item].name !== 'cloudinitdisk' && disks[item].bootOrder != null) {
|
var cdroms = []
|
||||||
disksarr[disks[item].bootOrder] = disks[item].name
|
this.formData.CDROMs = ''
|
||||||
maxIndex = Math.max(maxIndex, disks[item].bootOrder)
|
var maxIndex = 0
|
||||||
}
|
for (let item = 0; item < disks.length; item++) {
|
||||||
if (disks[item].cdrom != null) {
|
if (disks[item].name !== 'cloudinitdisk' && disks[item].bootOrder != null) {
|
||||||
cdroms.push(disks[item].name)
|
disksarr[disks[item].bootOrder] = disks[item].name
|
||||||
this.formData.CDROMs += disks[item].name + ' \n'
|
maxIndex = Math.max(maxIndex, disks[item].bootOrder)
|
||||||
|
}
|
||||||
|
if (disks[item].cdrom != null) {
|
||||||
|
cdroms.push(disks[item].name)
|
||||||
|
this.formData.CDROMs += disks[item].name + ' \n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.formData.bootOrder = ''
|
||||||
|
this.formData.Flavor = ''
|
||||||
|
for (var i = 0; i <= maxIndex; i++) {
|
||||||
|
if (disksarr[i] != null || typeof (disksarr[i]) !== 'undefined') {
|
||||||
|
this.formData.bootOrder += i + '. ' + disksarr[i] + ' \n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cpucore = data.spec.template.spec.domain.resources.limits.cpu
|
||||||
|
var memory = data.spec.template.spec.domain.resources.limits.memory
|
||||||
|
this.formData.Flavor += cpucore + ' vCPU, ' + memory + ' 内存'
|
||||||
|
this.formData2.Name = data.spec.template.spec.domain.devices.interfaces[0].name
|
||||||
|
this.formData2.Model = data.spec.template.spec.domain.devices.interfaces[0].model
|
||||||
|
var str = data.spec.template.metadata.annotations['harvesterhci.io/sshNames']
|
||||||
|
var arr = JSON.parse(str)
|
||||||
|
getSSHKey().then(n => {
|
||||||
|
this.sshkeyLists = []
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
for (let j = 0; j < n.data.length; j++) {
|
||||||
|
console.log(n.data[j])
|
||||||
|
if (n.data[j].id === arr[i]) {
|
||||||
|
this.sshkeyLists.push({ name: arr[i], sshKey: n.data[j].spec.publicKey })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.formData.bootOrder = ''
|
}
|
||||||
this.formData.Flavor = ''
|
|
||||||
for (var i = 0; i <= maxIndex; i++) {
|
|
||||||
if (disksarr[i] != null || typeof (disksarr[i]) !== 'undefined') {
|
|
||||||
this.formData.bootOrder += i + '. ' + disksarr[i] + ' \n'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var cpucore = data.spec.template.spec.domain.cpu.cores
|
|
||||||
var memory = data.spec.template.spec.domain.resources.requests.memory
|
|
||||||
this.formData.Flavor += cpucore + ' vCPU, ' + memory + ' Memory'
|
|
||||||
this.formData2.Name = data.spec.template.spec.domain.devices.interfaces[0].name
|
|
||||||
this.formData2.Model = data.spec.template.spec.domain.devices.interfaces[0].model
|
|
||||||
var str = data.spec.template.metadata.annotations['harvesterhci.io/sshNames']
|
|
||||||
var arr = JSON.parse(str)
|
|
||||||
getSSHKey().then(res => {
|
|
||||||
this.sshkeyLists = []
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
for (let j = 0; j < res.data.length; j++) {
|
|
||||||
console.log(res.data[j])
|
|
||||||
if (res.data[j].metadata.name === arr[i]) {
|
|
||||||
this.sshkeyLists.push({ name: arr[i], sshKey: res.data[j].spec.publicKey })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -108,7 +108,7 @@ export default {
|
||||||
</span>
|
</span>
|
||||||
} },
|
} },
|
||||||
{ prop: 'project', label: '项目' },
|
{ prop: 'project', label: '项目' },
|
||||||
{ prop: 'updateTime', label: '更新时间', formatter: (row) => new Date(row.updateTime).toLocaleString() },
|
{ prop: 'updateTime', label: '更新时间', formatter: (row) => new Date(row.data.status.conditions[1].lastUpdateTime).toLocaleString() || '-' },
|
||||||
{ prop: 'more', label: '操作', formatter: (row) => {
|
{ prop: 'more', label: '操作', formatter: (row) => {
|
||||||
return <div>
|
return <div>
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
|
|
|
@ -99,9 +99,14 @@ module.exports = {
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false
|
secure: false
|
||||||
},
|
},
|
||||||
'^/function': {
|
'^/jcc-faas-manager': {
|
||||||
ws: false,
|
ws: false,
|
||||||
target: 'https://jointcloud.net/api/'
|
target: 'https://jointcloud.net/apis/v1'
|
||||||
|
// changeOrigin: true,
|
||||||
|
},
|
||||||
|
'^/jcc-mall': {
|
||||||
|
ws: false,
|
||||||
|
target: 'https://jointcloud.net/apis/v1'
|
||||||
// changeOrigin: true,
|
// changeOrigin: true,
|
||||||
},
|
},
|
||||||
'/kapis/terminal.kubesphere.io': {
|
'/kapis/terminal.kubesphere.io': {
|
||||||
|
|
Loading…
Reference in New Issue