forked from JointCloud/JCC-RIP
merge from private branch
This commit is contained in:
parent
483d9fa56c
commit
cdb24ade09
|
@ -11759,10 +11759,9 @@
|
|||
}
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
|
||||
"dev": true
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/download/nanoid-1.0.2.tgz",
|
||||
"integrity": "sha512-sCTwJt690lduNHyqknXJp8pRwzm80neOLGaiTHU2KUJZFVSErl778NNCIivEQCX5gNT0xR1Jy3HEMe/TABT6lw=="
|
||||
},
|
||||
"nanomatch": {
|
||||
"version": "1.2.13",
|
||||
|
@ -13668,6 +13667,12 @@
|
|||
"postcss": "^8.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"nanoid": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
|
||||
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.3.11",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz",
|
||||
|
|
|
@ -1,13 +1,53 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// cpu 内存状态获取
|
||||
export function getUsageStatus() {
|
||||
// 概览统计
|
||||
export function getDashboardCounts() {
|
||||
return request({
|
||||
url: '/virtual/v1/metrics.k8s.io.nodes',
|
||||
url: '/virtual/v1/harvester/counts',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 概览事件
|
||||
export function getDashboardEvents() {
|
||||
return request({
|
||||
url: '/virtual/v1/harvester/events',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 概览info
|
||||
export function getDashboardInfo() {
|
||||
return request({
|
||||
url: '/virtual/v1/harvester/nodes',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 概览获取内存cpu使用量
|
||||
export function getUsageStatus() {
|
||||
return request({
|
||||
url: '/virtual/v1/harvester/pods',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 概览获取存储数据
|
||||
export function getStorageStatus() {
|
||||
return request({
|
||||
url: '/virtual/v1/harvester/longhorn.io.nodes',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// cpu 内存状态获取
|
||||
// export function getUsageStatus() {
|
||||
// return request({
|
||||
// url: '/virtual/v1/metrics.k8s.io.nodes',
|
||||
// method: 'get'
|
||||
// })
|
||||
// }
|
||||
|
||||
// cpu 内存状态获取
|
||||
export function getUsageStatusByName(name) {
|
||||
return request({
|
||||
|
@ -88,16 +128,24 @@ export function getDataVolume() {
|
|||
})
|
||||
}
|
||||
|
||||
// 虚拟机管理-卷列表 新
|
||||
export function getDataVolumeNew() {
|
||||
return request({
|
||||
url: '/virtual/v1/harvester/persistentvolumeclaims',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getDataVolumeYaml(name) {
|
||||
return request({
|
||||
url: '/virtual/apis/cdi.kubevirt.io/v1beta1/namespaces/default/datavolumes/' + name,
|
||||
url: '/virtual/api/v1/namespaces/default/persistentvolumeclaims/' + name,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function putDataVolumeYaml(name, yaml) {
|
||||
return request({
|
||||
url: '/virtual/v1/cdi.kubevirt.io.datavolumes/default/' + name,
|
||||
url: '/virtual/v1/harvester/persistentvolumeclaims/default/' + name,
|
||||
method: 'put',
|
||||
data: yaml
|
||||
})
|
||||
|
@ -105,14 +153,14 @@ export function putDataVolumeYaml(name, yaml) {
|
|||
|
||||
export function editDataVolume(name, data) {
|
||||
return request({
|
||||
url: '/virtual/v1/cdi.kubevirt.io.datavolumes/default/' + name,
|
||||
url: '/virtual/v1/harvester/persistentvolumeclaims/default/' + name,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function createDataVolume(data) {
|
||||
return request({
|
||||
url: '/virtual/v1/cdi.kubevirt.io.datavolumes',
|
||||
url: '/virtual/v1/harvester/persistentvolumeclaims',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
|
@ -120,7 +168,7 @@ export function createDataVolume(data) {
|
|||
|
||||
export function deleteDataVolume(name) {
|
||||
return request({
|
||||
url: '/virtual/v1/cdi.kubevirt.io.datavolumes/default/' + name,
|
||||
url: '/virtual/v1/harvester/persistentvolumeclaims/default/' + name,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
@ -169,6 +217,12 @@ export function createImages(data) {
|
|||
data: data
|
||||
})
|
||||
}
|
||||
export function deleteImage(name) {
|
||||
return request({
|
||||
url: '/virtual/v1/harvester/harvesterhci.io.virtualmachineimages/default/' + name,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
export function getImagesYaml(name) {
|
||||
return request({
|
||||
url: '/virtual/apis/harvesterhci.io/v1beta1/namespaces/default/virtualmachineimages/' + name,
|
||||
|
|
|
@ -47,6 +47,19 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
// 获取镜像列表
|
||||
getImagesList() {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + '/dockerhub/api/content/v1/products/search?image_filter=official&page_size=50&type=image',
|
||||
method: 'get'
|
||||
})
|
||||
},
|
||||
getImagesInfo(namespace, imageName) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/kapis/resources.kubesphere.io/v1alpha2/registry/blob?namespace=${namespace}&image=${imageName}`
|
||||
})
|
||||
},
|
||||
|
||||
getStorageInfo(clusterName, namespace, name) {
|
||||
return request({
|
||||
// 存储管理
|
||||
|
@ -89,15 +102,15 @@ export default {
|
|||
data: { metadata: { annotations: query.metadata.annotations }}
|
||||
})
|
||||
}
|
||||
if (classification === 'deployments') {
|
||||
return request({
|
||||
// 无传namespace是项目编辑信息的接口 /api/clusters/bj-member2/v1/namespaces/kube-federation-system
|
||||
// 工作负载里 部署,有状态副本集,守护进程集
|
||||
url: process.env.VUE_APP_BASE_API + `${namespace ? '/apis' + clusterName + '/apps' + '' : '/api' + clusterName}/v1/namespaces/${namespace ? namespace + '/' + (classification || 'deployments') + '/' + podName : podName}`,
|
||||
method: 'patch',
|
||||
data: query
|
||||
})
|
||||
}
|
||||
// if (classification === 'deployments') {
|
||||
return request({
|
||||
// 无传namespace是项目编辑信息的接口 /api/clusters/bj-member2/v1/namespaces/kube-federation-system
|
||||
// 工作负载里 部署,有状态副本集,守护进程集
|
||||
url: process.env.VUE_APP_BASE_API + `${namespace ? '/apis' + clusterName + '/apps' + '' : '/api' + clusterName}/v1/namespaces/${namespace ? namespace + '/' + (classification || 'deployments') + '/' + podName : podName}`,
|
||||
method: 'patch',
|
||||
data: query
|
||||
})
|
||||
// }
|
||||
},
|
||||
// 编辑配置文件
|
||||
editSetting(clusterName, namespace, name, query, classification) {
|
||||
|
@ -210,9 +223,55 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
// 工作负载提交前check
|
||||
getWorkloadCheck(clusterName, namespaces, type, name) {
|
||||
// http://10.105.20.3:30880/apis/clusters/fedjcce-ten002/apps/v1/namespaces/test-zhangjie/deployments?labelSelector=app%3Dasd
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/apis${clusterName}/apps/v1/namespaces/${namespaces}/${type}?labelSelector=app%3D${name}`,
|
||||
method: 'get',
|
||||
headers: {
|
||||
'x-check-exist': true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 工作负载新建
|
||||
getWorkloadCreate(clusterName, namespaces, type, data) {
|
||||
// http://10.105.20.3:30880/apis/clusters/fedjcce-ten002/apps/v1/namespaces/test-zhangjie/deployments?dryRun=All
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/apis${clusterName}/apps/v1/namespaces/${namespaces}/${type}?dryRun=All`,
|
||||
method: 'post',
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
},
|
||||
// 工作负载提交
|
||||
postWorkload(clusterName, namespaces, type, data) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/apis${clusterName}/apps/v1/namespaces/${namespaces}/${type}`,
|
||||
method: 'post',
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// http://119.45.100.73:30880/apis/apps/v1/namespaces/kubesphere-system/deployments/tower
|
||||
|
||||
// 工作负载名称check
|
||||
getWorkloadNameCheck(clusterName, type, name) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/apis${clusterName}/apps/v1/${type}/${name}`,
|
||||
method: 'get',
|
||||
headers: {
|
||||
'x-check-exist': true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 工作负载名称重复check
|
||||
getWorkloadNameCheck(clusterName, namespace, type, name) {
|
||||
getWorkloadNameandNamespaceCheck(clusterName, namespace, type, name) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/apis${clusterName}/v1/namespaces/${namespace}/${type}/${name}`,
|
||||
method: 'get',
|
||||
|
|
|
@ -74,7 +74,7 @@ export function getRamAverage(start, end, step) {
|
|||
// 计量计费接口总价格
|
||||
export function getMeasure(start, end, step) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + '/kapis/clusters/fedjcce-ten002/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=fedjcce-ten002',
|
||||
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: {
|
||||
|
@ -98,7 +98,7 @@ export function getRamLoad(start, end, step) {
|
|||
// 计量计费列表接口
|
||||
export function getMeteringList(start, end, step) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + '/kapis/clusters/fedjcce-ten002/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=fedjcce-ten002',
|
||||
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: {
|
||||
|
@ -110,7 +110,7 @@ export function getMeteringList(start, end, step) {
|
|||
// CPU整体负载接口
|
||||
export function getCpuAllload(start, end) {
|
||||
return request({
|
||||
url: '/monitoringscreen/api/v1/query_range?query=node_load15%7Binstance%3D~%22jcc-txy-001%22%7D&start=' + start + '&end=' + end + '&step=900&_=1645409802467',
|
||||
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: {
|
||||
|
|
|
@ -8,9 +8,9 @@ export function getServiceDetails(url1, url2) {
|
|||
})
|
||||
}
|
||||
// 服务创建
|
||||
export function createService(url, param) {
|
||||
export function createService(name, url, param) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/api/clusters/host/v1/namespaces/` + url + `/services`,
|
||||
url: process.env.VUE_APP_BASE_API + `/api${name}/v1/namespaces/` + url + `/services`,
|
||||
contentType: 'application/json',
|
||||
method: 'post',
|
||||
headers: {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 131 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -10,7 +10,7 @@
|
|||
<span class="tips">对容器的名称及容器的计算资源进行设置</span>
|
||||
</p>
|
||||
<el-form-item label="镜像" required="">
|
||||
<el-input v-model="createContainerForm.image" placeholder="点击右侧图标可选择镜像,或直接输入名称 例:nginx:latest">
|
||||
<el-input v-model="createContainerForm.image" placeholder="点击右侧图标可选择镜像,或直接输入名称 例:nginx:latest" @blur="selectMirror">
|
||||
<template slot="prepend">DockerHub</template>
|
||||
<el-select slot="append" v-model="createContainerForm.image" filterable class="selectPro" placeholder="选择已有镜像" @change="selectMirror">
|
||||
<el-option
|
||||
|
@ -62,36 +62,45 @@
|
|||
<span class="tips">设置容器的访问策略</span>
|
||||
</p>
|
||||
<div>
|
||||
<el-form-item
|
||||
v-for="(tag, index) in createContainerForm.ports"
|
||||
:key="'tag'+index"
|
||||
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>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>容器</td>
|
||||
<td>container-9lxa15</td>
|
||||
<td>
|
||||
<el-select v-model="createContainerForm.readOnly">
|
||||
<el-option
|
||||
v-for="item in mountOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</td>
|
||||
<td><el-input v-model="createContainerForm.mountPath" :disabled="!createContainerForm.readOnly || createContainerForm.readOnly === 'null'" placeholder="容器挂载路径, 例如: /data" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div>
|
||||
<el-form-item
|
||||
v-for="(tag, index) in createContainerForm.ports"
|
||||
:key="'tag'+index"
|
||||
label=""
|
||||
>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="7">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
content="为了充分利用应用治理的能力,请选择服务实际使用的协议。例如,如果服务暴露的是 HTTP 服务,则选择 http 协议,会生成形如 http-[name] 的端口名称。"
|
||||
placement="top-start"
|
||||
>
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
协议
|
||||
<el-select v-model="tag.protocol" @change="selectPolicy(tag)">
|
||||
<el-option
|
||||
v-for="item in protocolOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
名称
|
||||
<el-input v-model="tag.name" style="width:80%" />
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
容器端口
|
||||
<el-input v-model="tag.containerPort" style="width:80%" />
|
||||
</el-col>
|
||||
<el-col :span="3"><el-button icon="el-icon-delete" circle @click.prevent="removeTag(tag,index)" /></el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-button type="primary" plain round :disabled="addTagNumCheck" @click="addTag">添加端口</el-button>
|
||||
</div>
|
||||
</div></div></el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button icon="el-icon-close" circle @click="dialogVisible = false" />
|
||||
|
@ -113,7 +122,18 @@ export default {
|
|||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
return {
|
||||
ports: [],
|
||||
securityContext: {
|
||||
seLinuxOptions: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
namespace: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
// isEdit: {
|
||||
// type: Boolean,
|
||||
|
@ -122,15 +142,8 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
createContainerForm: {
|
||||
ports: [],
|
||||
securityContext: {
|
||||
seLinuxOptions: {}
|
||||
}
|
||||
},
|
||||
imageList: [],
|
||||
activeName: 'first',
|
||||
namespace: '',
|
||||
imageData: undefined,
|
||||
noImage: false,
|
||||
loading: false,
|
||||
|
@ -157,6 +170,14 @@ export default {
|
|||
this.$emit('input', value)
|
||||
}
|
||||
},
|
||||
createContainerForm: {
|
||||
get() {
|
||||
return this.formData
|
||||
},
|
||||
set(value) {
|
||||
// this.$emit('input', value)
|
||||
}
|
||||
},
|
||||
addTagNumCheck() {
|
||||
let flag = false
|
||||
this.createContainerForm.ports.forEach(e => {
|
||||
|
@ -169,11 +190,12 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
// 'createContainerForm.image'(newVal) {
|
||||
// throttle(this.selectMirror(), 300)
|
||||
// throttle(this.selectMirror(), 800)
|
||||
// }
|
||||
},
|
||||
mounted() {
|
||||
this.getVolumeList()
|
||||
moment.locale('zh-cn')
|
||||
this.getImageList()
|
||||
},
|
||||
methods: {
|
||||
selectPolicy(tag) {
|
||||
|
@ -188,12 +210,14 @@ export default {
|
|||
},
|
||||
selectMirror() {
|
||||
// 选中镜像
|
||||
if (!this.createContainerForm.image) {
|
||||
return false
|
||||
}
|
||||
this.loading = true
|
||||
this.$Api.getImagesInfo(this.namespace, this.createContainerForm.image).then(res => {
|
||||
// if status === 'fail'
|
||||
// 找不到镜像 重新选择
|
||||
// if status === 'succeeded'
|
||||
console.log(res.status)
|
||||
if (res.status === 'succeeded') {
|
||||
const layers = res.imageManifest.layers
|
||||
const size = layers.reduce((prev, layer) => prev + layer.size, 0)
|
||||
|
@ -241,7 +265,6 @@ export default {
|
|||
servicePort: containerPort
|
||||
}
|
||||
})
|
||||
console.log(ports)
|
||||
if (!isEmpty(ports)) {
|
||||
this.createContainerForm.ports = ports
|
||||
}
|
||||
|
@ -249,8 +272,10 @@ export default {
|
|||
ok() {
|
||||
// generate('0123456789abcdefghijklmnopqrstuvwxyz', length || 6)
|
||||
const container = Object.assign(this.createContainerForm)
|
||||
// TODO container名称修改待添加
|
||||
if (!this.createContainerForm.name) {
|
||||
container.name = 'container-' + generate('0123456789abcdefghijklmnopqrstuvwxyz', 6)
|
||||
container.imagePullPolicy = 'IfNotPresent'
|
||||
this.$emit('addImage', container)
|
||||
} else {
|
||||
this.$emit('editImage', container)
|
||||
|
@ -269,5 +294,18 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.border{
|
||||
border: 1px solid #DCDFE6;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.grayCard{
|
||||
background: #eeeeee;
|
||||
p{margin: 0;}
|
||||
.tips{
|
||||
margin-top: 0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
table td{padding: 0 5px; border: 0!important;}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -50,17 +50,17 @@
|
|||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<table>
|
||||
<tr>
|
||||
<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>container-9lxa15</td>
|
||||
<td>{{ item }}</td>
|
||||
<td>
|
||||
<el-select v-model="createVolumesForm.readOnly">
|
||||
<el-option
|
||||
v-for="item in mountOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
v-for="it in mountOptions"
|
||||
:key="it.value"
|
||||
:label="it.label"
|
||||
:value="it.value"
|
||||
/>
|
||||
</el-select>
|
||||
</td>
|
||||
|
|
|
@ -95,7 +95,7 @@ export default {
|
|||
this.$Api.editInfo(this.clusterName, formData.metadata.namespace || null, this.editInfoForm.name, formData, this.classification).then(res => {
|
||||
this.$message.success('操作成功')
|
||||
this.dialogFormVisible = false
|
||||
// this.$refs.multipleTable.getList()
|
||||
this.$emit('getList')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
|
||||
<script>
|
||||
import { createService, checkServiceName } from '@/api/second-class-page/serviceInfo'
|
||||
import { getStorageProject } from '@/api/one-class-page/storageManagement'
|
||||
import addKeyandValue from '@/components/addKeyandValue'
|
||||
import { validStorageName } from '@/utils/validate'
|
||||
|
||||
|
@ -193,7 +194,6 @@ export default {
|
|||
} else if (!validStorageName(value)) {
|
||||
callback(new Error('名称格式不合法'))
|
||||
} else {
|
||||
console.log(111)
|
||||
const res = await checkServiceName(this.clusterName, value, this.formData.namespace)
|
||||
if (res.exist) {
|
||||
callback(new Error('名称已存在。请使用其他名称。'))
|
||||
|
@ -305,7 +305,6 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
changeInput(current, target, key) {
|
||||
console.log(111)
|
||||
this.formData[target][key] = this.formData[current]
|
||||
},
|
||||
prev() {
|
||||
|
@ -316,9 +315,8 @@ export default {
|
|||
},
|
||||
// 项目列表拉取
|
||||
setFilterMapNamespaceList() {
|
||||
this.$Api.getNamespaceList().then(res => {
|
||||
const arr = res.items.map(e => { return { label: e.metadata.name, value: e.metadata.name, disabled: e.metadata.isFedManaged, isFedManaged: e.metadata.isFedManaged } })
|
||||
this.options1 = arr
|
||||
getStorageProject(this.clusterName, { page: 1, limit: 9999 }).then(res => {
|
||||
this.options1 = res.items.map(item => ({ label: item.metadata.name, value: item.metadata.name, disabled: item.metadata.isFedManaged, isFedManaged: item.metadata.isFedManaged }))
|
||||
})
|
||||
},
|
||||
create() {
|
||||
|
@ -363,9 +361,8 @@ export default {
|
|||
...this.formData.annotations
|
||||
}
|
||||
}
|
||||
console.log(volumeData)
|
||||
const url = this.formData.namespace
|
||||
createService(url, volumeData).then(res => {
|
||||
createService(this.clusterName, url, volumeData).then(res => {
|
||||
this.$message.success('创建成功')
|
||||
this.dialogSettingVisible = false
|
||||
this.$emit('getList')
|
||||
|
|
|
@ -61,11 +61,16 @@
|
|||
|
||||
<script>
|
||||
import { set } from 'lodash'
|
||||
import { getStorageProject } from '@/api/one-class-page/storageManagement'
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
classification: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -86,8 +91,7 @@ export default {
|
|||
},
|
||||
{ validator: this.nameValidator }
|
||||
]
|
||||
},
|
||||
namespace: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -111,7 +115,18 @@ export default {
|
|||
editInfoForm: {
|
||||
handler(newName, oldName) {
|
||||
// 执行代码
|
||||
this.submitInfoEdit()
|
||||
// console.log(newName)
|
||||
const { name, alias, description, namespace } = this.editInfoForm
|
||||
set(this.formData, 'metadata.labels.app', name)
|
||||
set(this.formData, 'metadata.name', name)
|
||||
set(this.formData, 'metadata.labels.app', name)
|
||||
set(this.formData, 'spec.selector.matchLabels.app', name)
|
||||
set(this.formData, 'spec.template.metadata.labels.app', name)
|
||||
set(this.formData, "metadata.annotations['kubesphere.io/alias-name']", alias)
|
||||
set(this.formData, "metadata.annotations['kubesphere.io/alias-description']", description)
|
||||
set(this.formData, "metadata.annotations['kubesphere.io/creator']", 'admin')
|
||||
set(this.formData, 'metadata.namespace', namespace)
|
||||
// set(this.formData, 'spec.template.metadata.annotations[logging.kubesphere.io/logsidecar-config]', '{}')
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
|
@ -121,24 +136,12 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
setFilterMapNamespaceList() {
|
||||
this.$Api.getNamespaceList().then(res => {
|
||||
const arr = res.items.map(e => { return { label: e.metadata.name, value: e.metadata.name, disabled: e.metadata.isFedManaged, isFedManaged: e.metadata.isFedManaged } })
|
||||
this.namespaceOptions = arr
|
||||
getStorageProject(this.clusterName, { page: 1, limit: 9999 }).then(res => {
|
||||
this.namespaceOptions = res.items.map(item => ({ label: item.metadata.name, value: item.metadata.name, disabled: item.metadata.isFedManaged, isFedManaged: item.metadata.isFedManaged }))
|
||||
})
|
||||
},
|
||||
submitInfoEdit() {
|
||||
// when formData is empty do this
|
||||
const { name, alias, description, namespace } = this.editInfoForm
|
||||
set(this.formData, 'metadata.labels.app', name)
|
||||
set(this.formData, 'metadata.name', name)
|
||||
set(this.formData, 'metadata.labels.app', name)
|
||||
set(this.formData, 'spec.selector.matchLabels.app', name)
|
||||
set(this.formData, 'spec.template.metadata.lables.app', name)
|
||||
set(this.formData, 'metadata.annotations[kubesphere.io/alias-name]', alias)
|
||||
set(this.formData, 'metadata.annotations[kubesphere.io/alias-description]', description)
|
||||
set(this.formData, 'metadata.annotations[kubesphere.io/creator]', 'admin')
|
||||
set(this.formData, 'metadata.namespace', namespace)
|
||||
set(this.formData, 'spec.template.metadata.annotations[logging.kubesphere.io/logsidecar-config]', '{}')
|
||||
|
||||
// this.formData = {
|
||||
// apiVersion: 'v1',
|
||||
|
@ -178,12 +181,20 @@ export default {
|
|||
// }
|
||||
// }
|
||||
},
|
||||
submitNameCheck() {
|
||||
this.$Api.getWorkloadNameandNamespaceCheck(this.clusterName, this.editInfoForm.namespace, this.classification, this.editInfoForm.name).then(res => {
|
||||
if (res.exist) {
|
||||
this.$message.warning('名称已存在')
|
||||
} else {
|
||||
this.$emit('checkSuccess', true)
|
||||
}
|
||||
})
|
||||
},
|
||||
nameValidator(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback()
|
||||
}
|
||||
|
||||
this.$Api.getWorkloadNameCheck(this.clusterName, this.namespace, this.type, value).then(res => {
|
||||
this.$Api.getWorkloadNameCheck(this.clusterName, this.classification, value).then(res => {
|
||||
if (res.exist) {
|
||||
return callback({ message: '名称已存在', field: rule.field })
|
||||
}
|
||||
|
|
|
@ -14,13 +14,14 @@
|
|||
</el-button>
|
||||
<div v-if="editInfoForm.spec.template.spec.containers">
|
||||
<div v-for="(item, index) in editInfoForm.spec.template.spec.containers" :key="index" class="dataList">
|
||||
<i class="el-icon-receiving" />
|
||||
<div>{{ item.name }}</div>
|
||||
<el-button icon="el-icon-delete" circle @click.prevent="removeContainer(index)" />
|
||||
<el-button icon="el-icon-edit" circle @click.prevent="editContainer(item)" />
|
||||
<div><i class="el-icon-receiving" />{{ item.name }}</div>
|
||||
<div>镜像:{{ item.image }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<addContainerForm v-model="containerFormVisiable" :form-data="formData" @addImage="addImage" @editImage="editImage" />
|
||||
<addContainerForm v-if="containerFormVisiable" v-model="containerFormVisiable" :namespace="editInfoForm.metadata.namespace" :form-data="containerForm" @addImage="addImage" @editImage="editImage" />
|
||||
<!-- <el-form-item
|
||||
prop="mirror"
|
||||
label="更新策略"
|
||||
|
@ -220,6 +221,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
containerForm: undefined,
|
||||
policysOptions,
|
||||
policysTypeOptions,
|
||||
namespaceOptions: [],
|
||||
|
@ -263,11 +265,14 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
addImage(data) {
|
||||
console.log(this.editInfoForm.spec.template.spec.containers)
|
||||
this.editInfoForm.spec.template.spec.containers.push(data)
|
||||
console.log(data)
|
||||
console.log(this.editInfoForm.spec.template.spec.containers.length)
|
||||
// console.log(data)
|
||||
this.containerForm = undefined
|
||||
},
|
||||
editImage(data) {
|
||||
console.log(data)
|
||||
// console.log(data)
|
||||
},
|
||||
setFilterMapNamespaceList() {
|
||||
this.$Api.getNamespaceList().then(res => {
|
||||
|
@ -280,6 +285,13 @@ export default {
|
|||
},
|
||||
removeTag(tag, index) {
|
||||
this.editTagForm.splice(index, 1)
|
||||
},
|
||||
removeContainer(index) {
|
||||
this.editInfoForm.spec.template.spec.containers.splice(index, 1)
|
||||
},
|
||||
editContainer(item) {
|
||||
this.containerForm = item
|
||||
this.containerFormVisiable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,6 +299,14 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
.createForm {
|
||||
.dataList{
|
||||
border: 1px solid #DCDFE6;
|
||||
margin-top: 10px;
|
||||
padding:10px;
|
||||
.el-button{
|
||||
float:right;
|
||||
}
|
||||
}
|
||||
.selectRadio{
|
||||
width: 100%;
|
||||
height: 50px!important;
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<template>
|
||||
<el-dialog v-if="createFormVisible" width="80%" title="创建项目" :visible.sync="createFormVisible">
|
||||
<el-dialog v-if="createFormVisible" width="80%" :title="'创建'+typeMap[classification]" :visible.sync="createFormVisible">
|
||||
<el-steps :active="stepNum" finish-status="success" simple>
|
||||
<el-step title="基本信息" />
|
||||
<el-step title="容器镜像" />
|
||||
<el-step title="挂载存储" />
|
||||
<el-step title="高级设置" />
|
||||
</el-steps>
|
||||
{{ metaData }}
|
||||
<basicInfoForm v-show="stepNum===0" v-model="metaData" />
|
||||
<basicInfoForm v-show="stepNum===0" ref="basicInfoForm" v-model="metaData" :classification="classification" @checkSuccess="handleCheckSuccess()" />
|
||||
<containerImage v-if="stepNum===1" v-model="metaData" />
|
||||
<mountVolumes v-if="stepNum===2" v-model="metaData" />
|
||||
<advancedSettings v-if="stepNum===3" v-model="metaData" />
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="createFormVisible = false">取 消</el-button>
|
||||
<el-button v-if="stepNum!==0" type="primary" @click="prev">上一步</el-button>
|
||||
<el-button 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>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
@ -46,6 +46,11 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
typeMap: {
|
||||
deployments: '部署',
|
||||
statefulsets: '有状态副本集',
|
||||
daemonsets: '守护进程集'
|
||||
},
|
||||
stepNum: 0,
|
||||
metaData: {},
|
||||
baseYaml: `apiVersion: apps/v1
|
||||
|
@ -57,11 +62,16 @@ spec:
|
|||
selector:
|
||||
matchLabels: {}
|
||||
template:
|
||||
metadata:
|
||||
metadata: {
|
||||
labels: {}
|
||||
}
|
||||
spec:
|
||||
containers: []
|
||||
serviceAccount: default
|
||||
affinity: {}
|
||||
initContainers: []
|
||||
volumes: []
|
||||
imagePullSecrets: null
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
|
@ -71,6 +81,13 @@ spec:
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
clusterName() {
|
||||
if (localStorage.getItem('clusterName') === 'default') {
|
||||
return ''
|
||||
} else {
|
||||
return '/clusters/' + localStorage.getItem('clusterName')
|
||||
}
|
||||
},
|
||||
createFormVisible: {
|
||||
get() {
|
||||
return this.value
|
||||
|
@ -85,6 +102,21 @@ spec:
|
|||
this.transformYaml()
|
||||
},
|
||||
methods: {
|
||||
createWorkload() {
|
||||
this.$Api.getWorkloadCheck(this.clusterName, this.metaData.metadata.namespace, this.classification, this.metaData.metadata.labels.app).then(res => {
|
||||
if (res.exist) {
|
||||
this.$message.warning('名称已存在')
|
||||
} else {
|
||||
this.$Api.getWorkloadCreate(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.createFormVisible = false
|
||||
this.$emit('getList')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
transformYaml() {
|
||||
this.metaData = JSON.parse(JSON.stringify(yaml.load(this.baseYaml), null, 2))
|
||||
},
|
||||
|
@ -92,6 +124,13 @@ spec:
|
|||
this.stepNum--
|
||||
},
|
||||
next() {
|
||||
if (this.stepNum === 0) {
|
||||
this.$refs.basicInfoForm.submitNameCheck()
|
||||
} else {
|
||||
this.stepNum++
|
||||
}
|
||||
},
|
||||
handleCheckSuccess() {
|
||||
this.stepNum++
|
||||
}
|
||||
}
|
||||
|
@ -101,4 +140,5 @@ spec:
|
|||
.el-steps{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<div>
|
||||
<p>挂载存储</p>
|
||||
|
||||
dataList
|
||||
<!-- dataList -->
|
||||
|
||||
<!-- <i class="el-icon-receiving" />
|
||||
<i class="el-icon-setting" />
|
||||
<i class="el-icon-key" /> -->
|
||||
|
@ -16,7 +17,7 @@
|
|||
<span class="tips">将配置文件或密钥挂载至指定目录</span>
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<addVolumesForm v-model="createFormVisible" :form-data="formData" @addVolumes="addVolumes" />
|
||||
<addVolumesForm v-model="createFormVisible" :form-data="editInfoForm" @addVolumes="addVolumes" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -24,6 +25,12 @@
|
|||
import addVolumesForm from '@/components/Actions/addVolumesForm.vue'
|
||||
export default {
|
||||
components: { addVolumesForm },
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
createFormVisible: false,
|
||||
|
@ -31,6 +38,16 @@ export default {
|
|||
formData: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editInfoForm: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addVolumes() {}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<div class="right-menu">
|
||||
<router-link v-if="routesType==='cluster'" class="selectBtn" to="/clusterSelect">多集群管理</router-link>
|
||||
<a class="selectBtn" @click="toContainerCost">计量计费</a>
|
||||
<!-- <a class="selectBtn" @click="toContainerCost">计量计费</a> -->
|
||||
<router-link class="selectBtn" to="/monitorSelect">资源管理</router-link>
|
||||
<template v-if="device!=='mobile'">
|
||||
<!-- <search id="header-search" class="right-menu-item" /> -->
|
||||
|
@ -87,18 +87,19 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
toMoniter() {
|
||||
const clusterName = localStorage.getItem('clusterName')
|
||||
switch (clusterName) {
|
||||
case 'fedjcce-member2':
|
||||
window.open('http://121.89.220.60:3000/d/9CWBz0bik/cluster-ali?orgId=1', '_blank')
|
||||
break
|
||||
case 'fedjcce-member1':
|
||||
window.open('http://121.89.220.60:3000/d/9CWBz0bi34/cluster-huawei?orgId=1', '_blank')
|
||||
break
|
||||
default:
|
||||
window.open('http://121.89.220.60:3000/d/9CWBz0bi/cluster-tencent?orgId=1', '_blank')
|
||||
break
|
||||
}
|
||||
// const clusterName = localStorage.getItem('clusterName')
|
||||
// switch (clusterName) {
|
||||
// case 'fedjcce-member2':
|
||||
// window.open('http://121.89.220.60:3000/d/9CWBz0bik/cluster-ali?orgId=1', '_blank')
|
||||
// break
|
||||
// case 'fedjcce-member1':
|
||||
// window.open('http://121.89.220.60:3000/d/9CWBz0bi34/cluster-huawei?orgId=1', '_blank')
|
||||
// break
|
||||
// default:
|
||||
// window.open('http://121.89.220.60:3000/d/9CWBz0bi/cluster-tencent?orgId=1', '_blank')
|
||||
// break
|
||||
// }
|
||||
window.open('https://www.jointcloud.net/dashboard/dashboards', '_blank')
|
||||
},
|
||||
toContainerCost() {
|
||||
this.$store.dispatch('user/setRouteType', 'containerCost')
|
||||
|
@ -120,14 +121,14 @@ export default {
|
|||
height: 60px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
// background: #fff;
|
||||
// box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
.selectBtn{
|
||||
line-height: 67px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
border-right: 1px solid #eeeeee;
|
||||
border-left: 1px solid #eeeeee;
|
||||
// border-right: 1px solid #eeeeee;
|
||||
// border-left: 1px solid #eeeeee;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.navbar .right-menu .right-menu-item.hover-effect{
|
||||
|
@ -164,6 +165,7 @@ export default {
|
|||
float: right;
|
||||
height: 100%;
|
||||
line-height: 50px;
|
||||
font-size: 14px;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
@ -172,7 +174,6 @@ export default {
|
|||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
color: #5a5e66;
|
||||
vertical-align: text-bottom;
|
||||
|
||||
|
|
|
@ -22,7 +22,18 @@ export default {
|
|||
// 删除接口 成功后
|
||||
this.$Api.deleteCurrent(this.clusterName, namespace, name, classification).then(res => {
|
||||
this.$message.success('删除成功')
|
||||
if (from === 'list') { this.$refs.multipleTable.getList() } else { this.goBack() }
|
||||
if (from === 'list') {
|
||||
if (text === '项目') {
|
||||
this.getList()
|
||||
setTimeout(() => {
|
||||
this.getList()
|
||||
}, 10000)
|
||||
} else {
|
||||
this.$refs.multipleTable.getList()
|
||||
}
|
||||
} else {
|
||||
this.goBack()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { login, blockChainLogin } from '@/api/user'
|
||||
import { login, harvesterLogin, blockChainLogin } from '@/api/user'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
import { resetRouter } from '@/router'
|
||||
|
||||
|
@ -57,14 +57,14 @@ const actions = {
|
|||
const { username, password } = userInfo
|
||||
return Promise.all([
|
||||
login({ 'username': username.trim(), 'encrypt': encrypt('kubesphere', password) }),
|
||||
// harvesterLogin({ 'username': 'admin', 'password': 'Nudt@123', 'description': 'UI Session', 'responseType': 'cookie', 'ttl': 57600000 }),
|
||||
harvesterLogin({ 'username': 'admin', 'password': 'xNudt@123456', 'description': 'UI Session', 'responseType': 'cookie', 'ttl': 57600000 }),
|
||||
blockChainLogin({
|
||||
'user': 'exploreradmin',
|
||||
'password': 'exploreradminpw',
|
||||
'network': 'agridepart-network'
|
||||
})]).then(response => {
|
||||
commit('SET_TOKEN', response[1].token)
|
||||
setToken(response[1].token)
|
||||
commit('SET_TOKEN', response[2].token)
|
||||
setToken(response[2].token)
|
||||
// Cookies.set('bToken', response[2].token)
|
||||
})
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@ import { getVolume } from '@/api/one-class-page/storageManagement'
|
|||
import { getNodeMessage, getNodeStatus } from '@/api/one-class-page/nodeManagement'
|
||||
import { getByValue } from '@/utils/data-process'
|
||||
import { getDaemonSets, getDeployments, getPods, getServices, getStatefulSets } from '@/api/one-class-page/workloadManagement'
|
||||
import { getUsageStatus, getVirtualHosts, getVirtualMachinesInstances, getDataVolume, getImages } from '@/api/one-class-page/virtualMachine'
|
||||
import { getUsageStatus, getVirtualHosts, getVirtualMachinesInstances, getDataVolumeNew, getImages } from '@/api/one-class-page/virtualMachine'
|
||||
// import { getImages } from '@/api/one-class-page/virtualMachine'
|
||||
import {
|
||||
getBriefSystemProject,
|
||||
|
@ -11,7 +11,7 @@ import {
|
|||
getDetailUserProject
|
||||
} from '@/api/one-class-page/projectManagement'
|
||||
import { getHostNum, getMemberNum } from '@/api/one-class-page/cluster'
|
||||
import { strToNumber } from '@/utils/data-process'
|
||||
// import { strToNumber } from '@/utils/data-process'
|
||||
|
||||
function getStatus(readyReplicas, replicas) {
|
||||
if (readyReplicas === replicas) {
|
||||
|
@ -242,7 +242,7 @@ const getUserProjectList = (clusterName, params) => {
|
|||
const customUrl = baseUrl + items.map(function(v) { return v.metadata.name }).join('%7C') + '%24&metrics_filter=namespace_cpu_usage%7Cnamespace_memory_usage_wo_cache%7Cnamespace_pod_count%24'
|
||||
getDetailUserProject(customUrl).then(re => {
|
||||
const { results } = re
|
||||
results.map((v) => { v.data.result.map((s) => { items[getByValue(namespace, s.metric.namespace)][v.metric_name] = s.value[1] }) })
|
||||
results.map((v) => { v.data?.result?.map((s) => { items[getByValue(namespace, s.metric.namespace)][v.metric_name] = s.value[1] }) })
|
||||
listResult = items
|
||||
resolve({ total: res.totalItems, rows: listResult })
|
||||
})
|
||||
|
@ -260,7 +260,7 @@ const getSystemProjectList = (clusterName, params) => {
|
|||
const customUrl = baseUrl + items.map(function(v) { return v.metadata.name }).join('%7C') + '%24&metrics_filter=namespace_cpu_usage%7Cnamespace_memory_usage_wo_cache%7Cnamespace_pod_count%24'
|
||||
getDetailSystemProject(customUrl).then(re => {
|
||||
const { results } = re
|
||||
results.map((v) => { v.data.result.map((s) => { items[getByValue(namespace, s.metric.namespace)][v.metric_name] = s.value[1] }) })
|
||||
results.map((v) => { v.data?.result?.map((s) => { items[getByValue(namespace, s.metric.namespace)][v.metric_name] = s.value[1] }) })
|
||||
listResult = items
|
||||
resolve({ total: res.totalItems, rows: listResult })
|
||||
})
|
||||
|
@ -293,7 +293,7 @@ const getVirtualMachineList = (clusterName, params) => {
|
|||
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.resources.requests.memory
|
||||
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']
|
||||
|
@ -322,7 +322,7 @@ const getVirtualHostList = () => {
|
|||
obj.aliveTime = res.data[item].metadata.fields[3]
|
||||
obj.aliveTime = obj.aliveTime.replace('d', '天')
|
||||
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
||||
obj.cpuUsed = parseFloat((parseInt(usage.data[item].usage.cpu) / 1000000000).toFixed(2))
|
||||
obj.cpuUsed = parseFloat((parseInt(usage?.data[item]?.usage?.cpu || 0) / 1000000000).toFixed(2))
|
||||
obj.cpuAll = parseInt(res.data[item].status.capacity.cpu)
|
||||
obj.cpuUsePercentage = parseFloat((obj.cpuUsed / obj.cpuAll).toFixed(2)) * 100
|
||||
obj.memoryUsed = parseFloat((parseInt(usage.data[item].usage.memory) / 1024 / 1024).toFixed(2))
|
||||
|
@ -347,37 +347,32 @@ const getVirtualHostList = () => {
|
|||
|
||||
const getDataVolumeList = () => {
|
||||
return new Promise(function(resolve) {
|
||||
const listResult = []
|
||||
getDataVolume().then((res) => {
|
||||
// console.log(res)
|
||||
|
||||
for (let item = 0; item < res.data.length; item++) {
|
||||
var obj = {}
|
||||
obj.index = item
|
||||
obj.name = res.data[item].metadata.name
|
||||
if (res.data[item].metadata.ownerReferences) { obj.state = 'In-Use' } else { obj.state = 'Ready' }
|
||||
obj.phase = res.data[item].metadata.fields[1]
|
||||
if (obj.phase !== null) { if (obj.phase === 'Pending') { obj.tagtype = 'warning' } else obj.tagtype = 'success' } else {
|
||||
obj.tagtype = 'info'
|
||||
obj.phase = '未运行'
|
||||
let listResult = []
|
||||
getDataVolumeNew().then((res) => {
|
||||
const data = res.data
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
listResult[i] = {
|
||||
namespace: data[i].metadata.namespace,
|
||||
index: i,
|
||||
name: data[i].metadata.name,
|
||||
tagtype: data[i].metadata.fields[1] === null ? 'info' : (data[i].metadata.fields[1] === 'Pending' ? 'warning' : 'success'),
|
||||
phase: data[i].metadata.fields[1],
|
||||
size: data[i].spec.resources.requests.storage,
|
||||
aliveTime: data[i].metadata.fields[6].replace('h', '小时').replace('d', '天').replace('m', '分'),
|
||||
creationTime: data[i].metadata.creationTimestamp,
|
||||
vm: ''
|
||||
}
|
||||
obj.progress = res.data[item].metadata.fields[2]
|
||||
if (obj.progress !== null) {
|
||||
if (obj.progress === 'N/A') { obj.state = 'Not-Ready' } else { obj.progress = strToNumber(obj.progress.slice(0, -1)) }
|
||||
} else obj.progress = 0
|
||||
obj.aliveTime = res.data[item].metadata.fields[4]
|
||||
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
||||
obj.aliveTime = obj.aliveTime.replace('d', '天')
|
||||
obj.aliveTime = obj.aliveTime.replace('m', '分')
|
||||
obj.creationTime = res.data[item].metadata.creationTimestamp
|
||||
if (res.data[item].metadata.ownerReferences) {
|
||||
obj.vm = res.data[item].metadata.ownerReferences[0].name
|
||||
} else { obj.vm = '' }
|
||||
obj.size = res.data[item].spec.pvc.resources.requests.storage
|
||||
listResult[item] = obj
|
||||
if (data[i].metadata.annotations['harvesterhci.io/owned-by']) {
|
||||
listResult[i].vm = JSON.parse(data[i].metadata.annotations['harvesterhci.io/owned-by'])[0].refs[0].replace('default/', '')
|
||||
}
|
||||
|
||||
// 状态判断
|
||||
const ownedBy = data[i].metadata?.annotations?.['harvesterhci.io/owned-by']
|
||||
const status = data[i].status?.phase === 'Bound' ? 'Ready' : 'NotReady'
|
||||
listResult[i].state = (ownedBy ? 'In-use' : status)
|
||||
}
|
||||
console.log(res)
|
||||
resolve({ total: res.data.length, rows: listResult })
|
||||
listResult = listResult.filter(n => n.namespace === 'default')
|
||||
resolve({ total: listResult.length, rows: listResult })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -385,7 +380,6 @@ const getImagesList = () => {
|
|||
return new Promise(function(resolve) {
|
||||
const listResult = []
|
||||
getImages().then((res) => {
|
||||
console.log(res)
|
||||
for (let item = 0; item < res.data.length; item++) {
|
||||
var obj = {}
|
||||
obj.index = item
|
||||
|
@ -393,10 +387,11 @@ const getImagesList = () => {
|
|||
obj.name = res.data[item].metadata.name
|
||||
obj.state = res.data[item].metadata.state.name
|
||||
obj.creationTime = res.data[item].metadata.creationTimestamp
|
||||
obj.aliveTime = res.data[item].metadata.fields[5]
|
||||
obj.aliveTime = res.data[item].metadata.fields[3]
|
||||
obj.size = Number((res.data[item].status.size / 1024 / 1024).toString().match(/^\d+(?:\.\d{0,2})?/)) + 'MB'
|
||||
obj.aliveTime = obj.aliveTime.replace('d', '天')
|
||||
obj.aliveTime = obj.aliveTime.replace('h', '小时')
|
||||
obj.aliveTime = obj.aliveTime.replace('m', '分钟')
|
||||
listResult[item] = obj
|
||||
}
|
||||
resolve({ total: res.data.length, rows: listResult })
|
||||
|
|
|
@ -20,13 +20,16 @@ service.interceptors.request.use(
|
|||
// do something before request is sent
|
||||
// kubesphere
|
||||
// Cookies.set('CSRF', '4d2f9a95f8')
|
||||
if (store.getters.token && config.url.indexOf('/virtual/') === -1 && config.url.indexOf('blockChain') === -1) {
|
||||
if (store.getters.token && config.url.indexOf('/virtual/') === -1 && config.url.indexOf('blockChain') === -1 && config.url.indexOf('dockerhub/api') === -1) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken()
|
||||
// kubesphere删除
|
||||
if (config.method === 'delete') {
|
||||
config.headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
}
|
||||
if (config.url.indexOf('dockerhub/api') > -1) {
|
||||
config.headers['Search-Version'] = 'v3'
|
||||
}
|
||||
// 区块链
|
||||
if (config.url.indexOf('blockChain') !== -1) {
|
||||
config.headers['Authorization'] = 'bearer ' + Cookies.get('bToken')
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
import { isString } from '@/utils/validate'
|
||||
// import SocialSign from './components/SocialSignin'
|
||||
import Cookies from 'js-cookie'
|
||||
// import { harvesterFirstLogin } from '@/api/user'
|
||||
import { harvesterFirstLogin } from '@/api/user'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
|
@ -166,9 +166,9 @@ export default {
|
|||
this.loading = true
|
||||
const csrf = Cookies.get('CSRF')
|
||||
if (!csrf) {
|
||||
// harvesterFirstLogin().then(() => {
|
||||
this.login()
|
||||
// })
|
||||
harvesterFirstLogin().then(() => {
|
||||
this.login()
|
||||
})
|
||||
} else {
|
||||
this.login()
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ export default {
|
|||
.then(() => {
|
||||
this.$message.success('登录成功')
|
||||
if (this.redirect) {
|
||||
if (this.redirect.indexOf('cluster') && !localStorage.getItem('clusterName')) {
|
||||
if (this.redirect.indexOf('cluster') > -1) {
|
||||
this.$router.push({ path: '/clusterSelect' })
|
||||
} else {
|
||||
this.$router.push({ path: this.redirect, query: this.otherQuery })
|
||||
|
|
|
@ -1,28 +1,69 @@
|
|||
<template>
|
||||
<div class="monitor-select">
|
||||
<Navbar />
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/cluster/overview')">
|
||||
<p>容器管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/virtual/overview')">
|
||||
<p>虚拟机管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/functions/overview')">
|
||||
<p>函数管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/blockChain/blockChainBrowser')">
|
||||
<p>块链管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="selectDiv">
|
||||
<el-row>
|
||||
<el-col :span="18">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<a @click="selectMonitor('/cluster/overview')">
|
||||
<div class="monitorSelectDiv">
|
||||
<div class="monitorSelectBtn">
|
||||
<img src="@/assets/img/cluster.png">
|
||||
<div>
|
||||
<div class="selectTitle">容器管理</div>
|
||||
<div>从容器维度中支持以跨云跨域多源异构方式,提供高性能可伸缩的容器应用管理服务。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<a @click="selectMonitor('/virtual/overview')">
|
||||
<div class="monitorSelectDiv">
|
||||
<div class="monitorSelectBtn">
|
||||
<img src="@/assets/img/virtual.png">
|
||||
<div>
|
||||
<div class="selectTitle">虚拟机管理</div>
|
||||
<div>在虚拟机的控制台中管理属于主机或群集的单个虚拟机或一组虚拟机。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<a @click="selectMonitor('/functions/overview')">
|
||||
<div class="monitorSelectDiv">
|
||||
<div class="monitorSelectBtn">
|
||||
<img src="@/assets/img/functions.png">
|
||||
<div>
|
||||
<div class="selectTitle">函数管理</div>
|
||||
<div>支持一个服务下对多个函数进行创建、编辑、运行,对函数运行全生命周期进行监控调度。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<a @click="selectMonitor('/blockChain/blockChainBrowser')">
|
||||
<div class="monitorSelectDiv">
|
||||
<div class="monitorSelectBtn">
|
||||
<img src="@/assets/img/blockChain.png">
|
||||
<div>
|
||||
<div class="selectTitle">块链管理</div>
|
||||
<div>构建于云际分布式框架之上,拥有去中心化信任机制、支持多组织资源分配模式。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<img class="logo" src="@/assets/img/bg_logo.png">
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -41,7 +82,7 @@ export default {
|
|||
methods: {
|
||||
selectMonitor(monitor) {
|
||||
this.$store.dispatch('user/setRouteType', monitor.split('/')[1])
|
||||
this.$router.push({ path: monitor })
|
||||
this.$router.push({ path: monitor.indexOf('cluster') > -1 ? 'clusterSelect' : monitor })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,15 +90,51 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
.monitor-select{
|
||||
.el-col a{
|
||||
display: block;
|
||||
width: 80%;
|
||||
margin: 30px auto;
|
||||
height: 80vh;
|
||||
padding: 30px;
|
||||
border: 1px solid #419ef4;
|
||||
border-radius: 30px;
|
||||
font-size: 24px;
|
||||
height: 100%;
|
||||
background: url('../../assets/img/monitorSelect_bg.png') center no-repeat;
|
||||
position: relative;
|
||||
.selectDiv{
|
||||
width: 100%;
|
||||
padding: 0 8% 0 15%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -300px;
|
||||
.el-col a{
|
||||
display: block;
|
||||
padding: 8%;
|
||||
font-size: 24px;
|
||||
margin: 4%;
|
||||
color: white;
|
||||
height: 280px;
|
||||
background: linear-gradient(29deg, #454B53, #454B53, #879AB2);
|
||||
border-radius: 36px;
|
||||
position: relative;
|
||||
}
|
||||
.el-col a:hover{
|
||||
background: linear-gradient(29deg, #0677E0, #127CDF, #5896EA);
|
||||
}
|
||||
.monitorSelectDiv{
|
||||
position: relative;
|
||||
top: 50%;
|
||||
margin-top: -50px;
|
||||
.monitorSelectBtn{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
>img{
|
||||
height: 30%;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.selectTitle{
|
||||
margin-bottom: 20px;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.logo{
|
||||
width: 100%;
|
||||
padding-top: 30%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div class="functionOverview">
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<!-- <el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img src="@/assets/img/hanshu-.png">
|
||||
<h4>函数概览</h4>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>函数调用概览</span>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<!-- <el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img src="@/assets/img/rq.png">
|
||||
<h4>容器概览</h4>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
<Pod />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<!-- <el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img src="@/assets/img/xnj-.png">
|
||||
<h4>虚拟机概览</h4>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
|
||||
<el-card shadow="never" class="virtualMachineChart">
|
||||
<h3>仪表盘</h3>
|
||||
<span>版本: {{ info.version }} 创建时间: {{ info.createTime + '前' }}</span>
|
||||
<el-divider />
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="8">
|
||||
<h4>cpu</h4>
|
||||
<div id="cpuGauge" ref="cpuGauge" />
|
||||
<p>cpu4中的0.39</p>
|
||||
<p>已预留 {{ cpuUsage }}/{{ cpuTotal }}</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<h4>内存</h4>
|
||||
<div id="memoryGauge" ref="memoryGauge" />
|
||||
<p>内存7.75GiB中的4.27</p>
|
||||
<p>已预留 {{ parseInt(memoryUsage/1024/1024/1024) }}/{{ parseInt(memoryTotal/1024/1024) + 'GiB' }}</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<h4>存储</h4>
|
||||
<div id="storageGauge" ref="storageGauge" />
|
||||
<p>存储197GiB中的9.84</p>
|
||||
<p>已使用 {{ (storageUsage/1024/1024/1024/1024).toFixed(2) }} / {{ (storageTotal/1024/1024/1024/1024).toFixed(2) }} TiB</p>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
@ -32,11 +36,11 @@
|
|||
<th>存储卷</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>2</td>
|
||||
<td>3</td>
|
||||
<td>2</td>
|
||||
<td>2</td>
|
||||
<td>{{ counts.host }}</td>
|
||||
<td>{{ counts.virtualMachine }}</td>
|
||||
<td>{{ counts.networking }}</td>
|
||||
<td>{{ counts.mirror }}</td>
|
||||
<td>{{ counts.volume }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>事件</h4>
|
||||
|
@ -51,51 +55,168 @@
|
|||
</template>
|
||||
|
||||
<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 * as echarts from 'echarts'
|
||||
|
||||
import { getDashboardCounts, getDashboardEvents, getDashboardInfo, getUsageStatus, getStorageStatus } from '@/api/one-class-page/virtualMachine'
|
||||
import moment from 'moment'
|
||||
export default {
|
||||
components: { List },
|
||||
data() {
|
||||
return {
|
||||
moment,
|
||||
info: {
|
||||
version: '',
|
||||
createTime: ''
|
||||
},
|
||||
counts: {
|
||||
host: '',
|
||||
virtualMachine: '',
|
||||
networking: '',
|
||||
mirror: '',
|
||||
volume: ''
|
||||
},
|
||||
columns: [
|
||||
{ prop: 'reason', label: '原因', width: '150' },
|
||||
{ prop: 'info', label: '资源信息' },
|
||||
{ prop: 'time', label: '发生时间', width: '150' }
|
||||
{ prop: 'info', label: '事件详情', formatter: (row) => {
|
||||
return <div>
|
||||
<span>{row.involvedObject.kind + ' ' + row.involvedObject.name}</span> <br />
|
||||
<span>{row.message}</span>
|
||||
</div>
|
||||
} },
|
||||
{ prop: 'lastTimestamp', label: '更新时间', width: '150', formatter: (row) => {
|
||||
return <div>{this.formatDate(row.lastTimestamp)}</div>
|
||||
} }
|
||||
],
|
||||
listData: [
|
||||
{
|
||||
reason: 'Created',
|
||||
info: 'VirtualMachineInstance educoder-main VirtualMachineInstance defined. ',
|
||||
time: '2021/4/23 9:40'
|
||||
},
|
||||
{
|
||||
reason: 'Started',
|
||||
info: 'VirtualMachineInstance educoder-main VirtualMachineInstance defined. ',
|
||||
time: '2021/4/23 9:40'
|
||||
},
|
||||
{
|
||||
reason: 'Stopped',
|
||||
info: 'VirtualMachineInstance educoder-main VirtualMachineInstance defined. ',
|
||||
time: '2021/4/23 9:40'
|
||||
}
|
||||
]
|
||||
|
||||
],
|
||||
cpuTotal: 0,
|
||||
memoryTotal: 0,
|
||||
storageTotal: 0,
|
||||
cpuUsage: 0,
|
||||
memoryUsage: 0,
|
||||
storageUsage: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$nextTick(() => {
|
||||
// 表格数据
|
||||
getDashboardCounts().then(res => {
|
||||
this.counts.host = res.data[0].counts.node.summary.count
|
||||
this.counts.virtualMachine = res.data[0].counts['kubevirt.io.virtualmachine'].summary.count
|
||||
this.counts.networking = res.data[0].counts['k8s.cni.cncf.io.networkattachmentdefinition'].summary.count
|
||||
this.counts.mirror = res.data[0].counts['harvesterhci.io.virtualmachineimage'].summary.count
|
||||
this.counts.volume = res.data[0].counts['longhorn.io.volume'].summary.count
|
||||
})
|
||||
// 事件数据
|
||||
getDashboardEvents().then(res => {
|
||||
this.listData = res.data
|
||||
})
|
||||
Promise.all([
|
||||
getDashboardInfo(), // cpu 内存 总量
|
||||
getUsageStatus(), // cpu 内存 使用量
|
||||
getStorageStatus()]).then(res => {
|
||||
res[0].data.forEach(element => {
|
||||
this.cpuTotal += Number(element.status.capacity.cpu)
|
||||
this.memoryTotal += Number(element.status.capacity.memory.replace('Ki', ''))
|
||||
if (element.metadata.fields[2].indexOf('master') > -1) {
|
||||
this.info.version = element.metadata.fields[7].replace('Harvester ', '')
|
||||
this.info.createTime = element.metadata.fields[3].replace('d', '天').replace('h', '小时')
|
||||
}
|
||||
})
|
||||
this.memoryUsage = 0
|
||||
this.cpuUsage = 0
|
||||
res[1].data.forEach(element => {
|
||||
const containers = element.spec.containers || []
|
||||
let memoryCounts = 0
|
||||
let cpuCounts = 0
|
||||
containers.forEach(e => {
|
||||
memoryCounts += this.parseSi(e?.resources?.requests?.memory || '0m', { increment: 1024 })
|
||||
cpuCounts += this.parseSi(e?.resources?.requests?.cpu || '0m')
|
||||
})
|
||||
this.memoryUsage += memoryCounts
|
||||
this.cpuUsage += cpuCounts
|
||||
})
|
||||
this.cpuUsage = parseInt(this.cpuUsage)
|
||||
this.storageUsage = 0
|
||||
this.storageTotal = 0
|
||||
res[2].data.forEach(element => {
|
||||
const diskStatus = element.status?.diskStatus || {}
|
||||
Object.values(diskStatus).map((disk) => {
|
||||
if (disk?.conditions?.Schedulable?.status === 'True' && disk?.storageAvailable && disk?.storageMaximum) {
|
||||
this.storageUsage += (disk.storageMaximum - disk.storageAvailable)
|
||||
}
|
||||
if (disk?.storageMaximum) {
|
||||
this.storageTotal += disk.storageMaximum
|
||||
}
|
||||
})
|
||||
})
|
||||
this.drawChart()
|
||||
})
|
||||
},
|
||||
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) {
|
||||
return moment(t).local().format('YYYY-MM-DD hh:mm:ss')
|
||||
},
|
||||
drawChart() {
|
||||
const cpuGauge = echarts.init(this.$refs.cpuGauge)
|
||||
cpuGauge.setOption(this.returnGaugeOption(5))
|
||||
cpuGauge.setOption(this.returnGaugeOption((this.cpuUsage / this.cpuTotal).toFixed(4) * 100))
|
||||
const memoryGauge = echarts.init(this.$refs.memoryGauge)
|
||||
memoryGauge.setOption(this.returnGaugeOption(16))
|
||||
memoryGauge.setOption(this.returnGaugeOption((parseInt(this.memoryUsage / 1024 / 1024 / 1024) / parseInt(this.memoryTotal / 1024 / 1024)).toFixed(4) * 100))
|
||||
const storageGauge = echarts.init(this.$refs.storageGauge)
|
||||
storageGauge.setOption(this.returnGaugeOption(3))
|
||||
storageGauge.setOption(this.returnGaugeOption(((this.storageUsage / 1024 / 1024 / 1024 / 1024).toFixed(2) / (this.storageTotal / 1024 / 1024 / 1024 / 1024).toFixed(2)).toFixed(4) * 100))
|
||||
},
|
||||
returnGaugeOption(data) {
|
||||
return {
|
||||
|
|
|
@ -101,7 +101,7 @@ export default {
|
|||
this.$Api.addInfo(this.clusterName, formData).then(res => {
|
||||
this.$message.success('操作成功')
|
||||
this.createFormVisible = false
|
||||
this.doSearch()
|
||||
this.$emit('getList')
|
||||
})
|
||||
},
|
||||
nameValidator(rule, value, callback) {
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
将根据项目资源进行分组, 可以按项目对资源进行查看管理</span>
|
||||
<el-button v-if="activeName ==='0'" class="create-btn" type="primary" @click="createFormVisible = true">创建</el-button>
|
||||
</el-card>
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" />
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" @getList="getList" />
|
||||
<el-card shadow="never">
|
||||
<el-tabs v-model="activeName" @tab-click="switchTab">
|
||||
<el-tab-pane key="userProject" label="用户项目">
|
||||
<List
|
||||
ref="multipleTable"
|
||||
ref="multipleTable1"
|
||||
class="multipleTable"
|
||||
:columns="columns[0]"
|
||||
func-name="getUserProjectList"
|
||||
|
@ -24,7 +24,7 @@
|
|||
</el-tab-pane>
|
||||
<el-tab-pane key="systemProject" label="系统项目">
|
||||
<List
|
||||
ref="multipleTable"
|
||||
ref="multipleTable2"
|
||||
class="multipleTable"
|
||||
:columns="columns[1]"
|
||||
func-name="getSystemProjectList"
|
||||
|
@ -36,7 +36,7 @@
|
|||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
<CreateProject v-model="createFormVisible" :do-search="doSearch" />
|
||||
<CreateProject v-model="createFormVisible" @getList="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -69,7 +69,7 @@ export default {
|
|||
[
|
||||
{ prop: 'name', label: '名称', formatter: (row) => { return <a onClick={() => this.viewUserProjectDetail(row)}>{row.metadata.name}</a> } },
|
||||
{ prop: 'status', label: '状态', formatter: (row, column) => { return row.status.phase === 'Active' ? '活跃' : '准备中' } },
|
||||
{ prop: 'space', label: '企业空间', formatter: (row, column) => { return row.metadata.labels['kubesphere.io/workspace'] || '-' } },
|
||||
// { prop: 'space', label: '企业空间', formatter: (row, column) => { return row.metadata.labels['kubesphere.io/workspace'] || '-' } },
|
||||
{ prop: 'namespace_cpu_usage', label: 'CPU使用量' },
|
||||
{ prop: 'namespace_memory_usage_wo_cache', label: '内存使用量' },
|
||||
{ prop: 'namespace_pod_count', label: 'Pods数量' },
|
||||
|
@ -80,7 +80,6 @@ export default {
|
|||
</el-button>
|
||||
<el-dropdown-menu slot='dropdown'>
|
||||
<span onClick={() => this.editBaseInfo(row)}> <el-dropdown-item> 编辑</el-dropdown-item> </span>
|
||||
<span onClick={() => this.setSpace(row)}> <el-dropdown-item> 分配企业空间 </el-dropdown-item> </span>
|
||||
<span onClick={() => this.deleteCurrent('项目', row.metadata.name, row.metadata.name, 'userProject', 'list')}> <el-dropdown-item> 删除</el-dropdown-item> </span>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
@ -90,7 +89,7 @@ export default {
|
|||
[
|
||||
{ prop: 'name', label: '名称', formatter: (row) => { return <a onClick={() => this.viewSystemProjectDetail(row)}>{row.metadata.name}</a> } },
|
||||
{ prop: 'status', label: '状态', formatter: (row, column) => { return row.status.phase === 'Active' ? '活跃' : '准备中' } },
|
||||
{ prop: 'space', label: '企业空间', formatter: (row, column) => { return row.metadata.labels['kubesphere.io/workspace'] || '-' } },
|
||||
// { prop: 'space', label: '企业空间', formatter: (row, column) => { return row.metadata.labels['kubesphere.io/workspace'] || '-' } },
|
||||
{ prop: 'namespace_cpu_usage', label: 'CPU使用量' },
|
||||
{ prop: 'namespace_memory_usage_wo_cache', label: '内存使用量' },
|
||||
{ prop: 'namespace_pod_count', label: 'Pods数量' },
|
||||
|
@ -133,8 +132,9 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.$refs.multipleTable.getList()
|
||||
getList() {
|
||||
this.$refs.multipleTable1.getList()
|
||||
this.$refs.multipleTable2.getList()
|
||||
},
|
||||
switchTab(e) {
|
||||
const tab = this.tabList[e.index]
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!-- <el-dialog title="查看配置文件" :visible.sync="dialogSettingVisible">
|
||||
<codemirror v-model="code" class="code-mirror" :options="cmOption" />
|
||||
</el-dialog> -->
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" />
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" @getList="getList" />
|
||||
<ServiceCreate v-model="dialogSettingVisible" @getList="getList" />
|
||||
<!-- <el-dialog :visible.sync="dialogSettingVisible">
|
||||
<Service class="demo1" />
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
>
|
||||
<el-slider
|
||||
v-model="editInfoForm2.storage"
|
||||
style="margin-top: 30px;width:90%"
|
||||
style="margin-top:30px;word-break:keep-all;"
|
||||
:marks="marks"
|
||||
show-input
|
||||
:max="2050"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
存储卷供用户创建的工作负载使用,是将工作负载数据持久化的一种资源对象。 </span>
|
||||
<el-button type="primary" class="create-btn" @click="dialogCreateVisible = true">创建</el-button>
|
||||
</el-card>
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" classification="storage" />
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" classification="storage" @getList="getList" />
|
||||
<el-card shadow="never">
|
||||
<List
|
||||
ref="multipleTable"
|
||||
|
@ -49,7 +49,16 @@ export default {
|
|||
},
|
||||
status: {
|
||||
label: '状态',
|
||||
type: 'select'
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '准备就绪', value: 'bound'
|
||||
}, {
|
||||
label: '丢失', value: 'lost'
|
||||
}, {
|
||||
label: '等待中', value: 'pending'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
|
|
|
@ -44,12 +44,12 @@
|
|||
<el-form-item label="大小">
|
||||
<el-input
|
||||
v-model="formData.size"
|
||||
:disabled="!clone"
|
||||
:disabled="isDisabled"
|
||||
><template slot="append">GIB</template></el-input>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="标签">
|
||||
<!-- <el-tab-pane label="标签">
|
||||
<h4>标签</h4>
|
||||
<div v-for="(item, index) in formData.tag" :key="item.id">
|
||||
<el-form-item>
|
||||
|
@ -62,7 +62,7 @@
|
|||
</el-form-item>
|
||||
</div>
|
||||
<el-button type="primary" :disabled="isDisabled" @click="addTag">添加</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tab-pane> -->
|
||||
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
|
@ -78,7 +78,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { getImages, getDataVolume, editDataVolume } from '@/api/one-class-page/virtualMachine'
|
||||
import { getImages, getDataVolumeNew, editDataVolume } from '@/api/one-class-page/virtualMachine'
|
||||
import { createDataVolume } from '@/api/one-class-page/virtualMachine'
|
||||
export default {
|
||||
data() {
|
||||
|
@ -158,7 +158,7 @@ export default {
|
|||
getFormData() {
|
||||
this.formData.name = this.$route.query.name
|
||||
this.formData.size = this.$route.query.size.slice(0, -2)
|
||||
getDataVolume().then(res => {
|
||||
getDataVolumeNew().then(res => {
|
||||
this.Data = res.data[this.$route.query.index]
|
||||
if (this.Data.metadata.annotations['field.cattle.io/description'] != null && typeof (this.Data.metadata.annotations['field.cattle.io/description']) !== 'undefined') {
|
||||
this.formData.description = this.Data.metadata.annotations['field.cattle.io/description']
|
||||
|
@ -213,10 +213,7 @@ export default {
|
|||
},
|
||||
editVolume() {
|
||||
this.Data.metadata.annotations['field.cattle.io/description'] = this.formData.description
|
||||
this.Data.metadata.labels = {}
|
||||
for (let item = 0; item < this.formData.tag.length; item++) {
|
||||
this.Data.metadata.labels[this.formData.tag[item].key] = this.formData.tag[item].value
|
||||
}
|
||||
this.Data.spec.resources.requests.storage = this.formData.size + 'Gi'
|
||||
editDataVolume(this.$route.query.name, this.Data).then(res => {
|
||||
console.log(res)
|
||||
this.$message.success('修改成功')
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="标签">
|
||||
<!-- <el-tab-pane label="标签">
|
||||
<h4>标签</h4>
|
||||
<div v-for="(item, index) in formData.tag" :key="item.id">
|
||||
<el-form-item>
|
||||
|
@ -63,7 +63,7 @@
|
|||
</el-form-item>
|
||||
</div>
|
||||
<el-button type="primary" @click="addTag">添加</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tab-pane> -->
|
||||
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
|
@ -100,32 +100,7 @@ export default {
|
|||
label: 'VM Image'
|
||||
}],
|
||||
options2: [],
|
||||
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: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
volumeData: {},
|
||||
// 校验规则
|
||||
rules: {
|
||||
name: [
|
||||
|
@ -157,7 +132,6 @@ export default {
|
|||
const obj = {}
|
||||
obj.value = data[item].id
|
||||
obj.label = data[item].metadata.fields[1]
|
||||
console.log(data[item].metadata.fields[1])
|
||||
this.options2.push(obj)
|
||||
}
|
||||
})
|
||||
|
@ -179,16 +153,29 @@ export default {
|
|||
this.formData.tag.splice(index, 1)
|
||||
},
|
||||
create() {
|
||||
this.volumeData.metadata.annotations['field.cattle.io/description'] = this.formData.description
|
||||
if (this.formData.resourceType === 'VM Image') this.volumeData.metadata.annotations['harvesterhci.io/imageId'] = this.formData.imageId
|
||||
for (let item = 0; item < this.formData.tag.length; item++) {
|
||||
this.volumeData.metadata.labels[this.formData.tag[item].key] = this.formData.tag[item].value
|
||||
this.volumeData = {
|
||||
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'
|
||||
// console.log(this.volumeData)
|
||||
createDataVolume(this.volumeData).then(res => {
|
||||
console.log(res)
|
||||
this.$message.success('创建成功')
|
||||
this.goBack()
|
||||
})
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<script>
|
||||
import { FormData } from '@/components/FormData'
|
||||
import { getImages, getDataVolume } from '@/api/one-class-page/virtualMachine'
|
||||
import { getImages, getDataVolumeNew } from '@/api/one-class-page/virtualMachine'
|
||||
|
||||
export default {
|
||||
components: { FormData },
|
||||
|
@ -79,7 +79,7 @@ export default {
|
|||
var images = null
|
||||
getImages().then(res => {
|
||||
images = res.data
|
||||
getDataVolume().then(res => {
|
||||
getDataVolumeNew().then(res => {
|
||||
var data = res.data[this.index]
|
||||
if (data.metadata.annotations['harvesterhci.io/imageId'] != null && typeof (data.metadata.annotations['harvesterhci.io/imageId']) !== 'undefined' && data.metadata.annotations['harvesterhci.io/imageId'] !== '') {
|
||||
var imageId = data.metadata.annotations['harvesterhci.io/imageId']
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
:columns="columns"
|
||||
func-name="getDataVolumeList"
|
||||
:cluster-name="clusterName"
|
||||
:pagination="true"
|
||||
:pagination="false"
|
||||
tooltip-effect="dark"
|
||||
/>
|
||||
</el-card>
|
||||
|
@ -69,7 +69,6 @@ export default {
|
|||
{ prop: 'name', label: '名称', formatter: (row) => { return <a onClick={() => this.viewVolumeDetail(row)}>{row.name}</a> } },
|
||||
{ prop: 'size', label: '大小' },
|
||||
{ prop: 'vm', label: '挂载虚拟机', formatter: (row) => { return <a onClick={() => this.viewVMDetail(row)}>{row.vm}</a> } },
|
||||
{ prop: 'progress', label: '进度', formatter: (row) => { return <el-progress percentage={row.progress}></el-progress> } },
|
||||
{ prop: 'phase', label: '阶段', formatter: (row) => { return <el-tag type={row.tagtype}>{row.phase}</el-tag> } },
|
||||
{ prop: 'aliveTime', label: '存活时间', formatter: (row) => { return <el-tooltip effect='light' content={row.creationTime} placement='right'><span>{row.aliveTime}</span></el-tooltip> } },
|
||||
{
|
||||
|
@ -105,11 +104,6 @@ export default {
|
|||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
this.timer = setInterval(() => {
|
||||
this.$refs.multipleTable.getList()
|
||||
}, this.timeInterval)
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
|
@ -170,9 +164,8 @@ export default {
|
|||
document.body.removeChild(link)
|
||||
})
|
||||
},
|
||||
deleteDataVolumes(name) {
|
||||
deleteDataVolume(name).then(res => {
|
||||
console.log(res)
|
||||
async deleteDataVolumes(name) {
|
||||
await deleteDataVolume(name).then(res => {
|
||||
this.deleteDialogVisible = false
|
||||
this.$message.success('删除成功')
|
||||
})
|
||||
|
|
|
@ -26,12 +26,24 @@
|
|||
tooltip-effect="dark"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
title="您确定要删除吗?"
|
||||
:visible.sync="deleteDialogVisible"
|
||||
width="30%"
|
||||
>
|
||||
<span>您试图删除 镜像 {{ clickrow.name }} </span>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="deleteDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="deleteDataImage(clickrow.name)">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import { getImagesYaml } from '@/api/one-class-page/virtualMachine'
|
||||
import { getImagesYaml, deleteImage } from '@/api/one-class-page/virtualMachine'
|
||||
|
||||
export default {
|
||||
name: 'PodForm',
|
||||
|
@ -41,6 +53,8 @@ export default {
|
|||
timer: null,
|
||||
timeInterval: 10000,
|
||||
disabled: false,
|
||||
deleteDialogVisible: false,
|
||||
clickrow: '',
|
||||
filterMap: {
|
||||
// name: {
|
||||
// label: '名称'
|
||||
|
@ -121,10 +135,19 @@ export default {
|
|||
this.downloadHostYaml(row.name)
|
||||
break
|
||||
case 5:
|
||||
this.deleteDialogVisible = true
|
||||
this.clickrow = row
|
||||
break
|
||||
default:
|
||||
}
|
||||
},
|
||||
async deleteDataImage(name) {
|
||||
await deleteImage(name).then(() => {
|
||||
this.deleteDialogVisible = false
|
||||
this.$message.success('删除成功')
|
||||
})
|
||||
this.$refs.multipleTable.getList()
|
||||
},
|
||||
viewVMDetail(row) {
|
||||
this.$router.push({ path: `virtual-machine/detail`, query: row })
|
||||
},
|
||||
|
|
|
@ -71,21 +71,7 @@ export default {
|
|||
url: '',
|
||||
tag: []
|
||||
},
|
||||
imagesData: {
|
||||
type: 'harvesterhci.io.virtualmachineimage',
|
||||
metadata: {
|
||||
annotations: {
|
||||
'field.cattle.io/description': ''
|
||||
},
|
||||
generateName: 'image-',
|
||||
labels: {},
|
||||
namespace: 'default'
|
||||
},
|
||||
spec: {
|
||||
displayName: '',
|
||||
url: ''
|
||||
}
|
||||
},
|
||||
imagesData: {},
|
||||
// 校验规则
|
||||
rules: {
|
||||
name: [
|
||||
|
@ -98,7 +84,7 @@ export default {
|
|||
url: [
|
||||
{
|
||||
required: true, // 是否必填
|
||||
message: '大小不能为空', // 规则提示
|
||||
message: '地址不能为空', // 规则提示
|
||||
trigger: 'blur' // 何事件触发
|
||||
}
|
||||
]
|
||||
|
@ -124,18 +110,35 @@ export default {
|
|||
this.formData.tag.splice(index, 1)
|
||||
},
|
||||
create() {
|
||||
this.imagesData.metadata.annotations['field.cattle.io/description'] = this.formData.description
|
||||
for (let item = 0; item < this.formData.tag.length; item++) {
|
||||
this.imagesData.metadata.labels[this.formData.tag[item].key] = this.formData.tag[item].value
|
||||
}
|
||||
this.imagesData.spec.displayName = this.formData.name
|
||||
this.imagesData.metadata.generateName = 'img'
|
||||
this.imagesData.spec.url = this.formData.url
|
||||
console.log(this.imagesData)
|
||||
createImages(this.imagesData).then(res => {
|
||||
console.log(res)
|
||||
this.$message.success('创建成功')
|
||||
this.goBack()
|
||||
this.$refs['formData'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.imagesData = {
|
||||
'type': 'harvesterhci.io.virtualmachineimage',
|
||||
'metadata': {
|
||||
annotations: {
|
||||
'field.cattle.io/description': this.formData.description
|
||||
},
|
||||
labels: {},
|
||||
'namespace': 'default',
|
||||
'generateName': 'image-'
|
||||
},
|
||||
'spec': {
|
||||
'sourceType': 'download',
|
||||
'displayName': this.formData.name,
|
||||
'url': this.formData.url
|
||||
}
|
||||
}
|
||||
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()
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<span class="tips">
|
||||
工作负载 (Workload) 通常是访问服务的实际载体, 也是对节点日志收集、监控等系统应用的实际运行载体,是对一组容器组 (Pod) 的抽象模型。</span>
|
||||
</el-card>
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" :classification="tabList[activeName]" />
|
||||
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" :classification="tabList[activeName]" @getList="getList" />
|
||||
<el-card shadow="never">
|
||||
<el-tabs v-model="activeName" @tab-click="switchTab">
|
||||
<el-tab-pane key="deployments" label="部署">
|
||||
|
@ -52,7 +52,7 @@
|
|||
</el-tabs>
|
||||
</el-card>
|
||||
<EditSetting v-model="dialogSettingVisible" :is-edit="true" :code="code" @submitSettingEdit="submitSettingEdit" />
|
||||
<CreateWorkload v-model="createFormVisible" />
|
||||
<CreateWorkload v-model="createFormVisible" :classification="tabList[activeName]" @getList="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -63,6 +63,7 @@ import deleteCurrent from '@/mixin/deleteCurrent'
|
|||
import editSetting from '@/mixin/editSetting'
|
||||
import { statusOptions } from '@/utils/map'
|
||||
import CreateWorkload from '@/components/workloadsManagement/createWorkload'
|
||||
import { getStorageProject } from '@/api/one-class-page/storageManagement'
|
||||
|
||||
export default {
|
||||
name: 'WorkloadForm',
|
||||
|
@ -152,7 +153,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
setFilterMapNamespaceList() {
|
||||
this.$Api.getNamespaceList().then(res => {
|
||||
getStorageProject(this.clusterName, { page: 1, limit: 9999 }).then(res => {
|
||||
const arr = res.items.map(e => { return { label: e.metadata.name, value: e.metadata.name } })
|
||||
this.filterMap.namespace.dataSource = arr
|
||||
})
|
||||
|
@ -166,6 +167,9 @@ export default {
|
|||
viewDetail(row) {
|
||||
this.$router.push({ path: `${row.project}/${this.tabList[this.activeName]}/${row.name}/resource-status` })
|
||||
},
|
||||
getList() {
|
||||
this.$refs.multipleTable.getList()
|
||||
},
|
||||
// 重新部署
|
||||
reDeploy(row) {
|
||||
const query = { 'spec': { 'template': { 'metadata': { 'annotations': { 'kubesphere.io/restartedAt': new Date().toISOString() }}}}}
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports = {
|
|||
proxy: {
|
||||
'^/login': {
|
||||
ws: false,
|
||||
target: 'http://10.105.20.3:30880/'/* Host */
|
||||
target: 'https://jointcloud.net/prod-api/'/* Host */
|
||||
},
|
||||
// '^/v1': {
|
||||
// ws: false,
|
||||
|
@ -57,12 +57,13 @@ module.exports = {
|
|||
// ws: true,
|
||||
// target: 'http://124.71.196.205:30881/' /* EduCoder */
|
||||
// target: 'http://119.3.157.144:30881/', /* KubeX */
|
||||
target: 'http://10.105.20.3:30880/'/* Host */
|
||||
// target: 'http://10.105.20.3:30880/'/* Host */
|
||||
target: 'https://jointcloud.net/prod-api/'/* Host */
|
||||
// target: 'http://39.103.233.49:30881/', /* BJ-Member2 */
|
||||
// changeOrigin: true,
|
||||
},
|
||||
'^/dockerhub/api/': {
|
||||
target: 'http://119.45.100.73:30880/'
|
||||
target: 'http://10.105.20.3:30880/'
|
||||
// pathRewrite: {
|
||||
// '^/dockerhub': '/api'
|
||||
// },
|
||||
|
|
Loading…
Reference in New Issue